OSDN Git Service

Merge pull request #23 from Bytom/dev
authorwz <mars@bytom.io>
Mon, 10 Dec 2018 01:01:03 +0000 (09:01 +0800)
committerGitHub <noreply@github.com>
Mon, 10 Dec 2018 01:01:03 +0000 (09:01 +0800)
Dev

58 files changed:
account/accounts.go
api/api.go
api/cliam_transact.go [new file with mode: 0644]
api/main_transact.go [new file with mode: 0644]
api/query.go
api/receivers.go
api/transact.go
blockchain/txbuilder/mainchain/constraint.go
blockchain/txbuilder/mainchain/rawtxsig_witness.go
blockchain/txbuilder/mainchain/signing_instruction.go
blockchain/txbuilder/mainchain/types.go
docs/vapor-deployment.md
equity/equity/LockWith2of3Keys [new file with mode: 0644]
equity/pegin_contract/pegin_contract.go [new file with mode: 0644]
node/node.go
protocol/bc/bc.pb.go
protocol/bc/bc.proto
protocol/bc/bytom_blockheader.go [moved from protocol/bc/types/bytom/blockheader.go with 57% similarity]
protocol/bc/types/bytom/asset.go [deleted file]
protocol/bc/types/bytom/asset_test.go [deleted file]
protocol/bc/types/bytom/bc.pb.go [deleted file]
protocol/bc/types/bytom/bc.proto [deleted file]
protocol/bc/types/bytom/block.go
protocol/bc/types/bytom/coinbase.go [deleted file]
protocol/bc/types/bytom/entry.go [deleted file]
protocol/bc/types/bytom/entry_test.go [deleted file]
protocol/bc/types/bytom/general.go
protocol/bc/types/bytom/hash.go [deleted file]
protocol/bc/types/bytom/issuance.go [deleted file]
protocol/bc/types/bytom/mux.go [deleted file]
protocol/bc/types/bytom/output.go [deleted file]
protocol/bc/types/bytom/retirement.go [deleted file]
protocol/bc/types/bytom/spend.go [deleted file]
protocol/bc/types/bytom/tx.go
protocol/bc/types/bytom/tx_status.go [deleted file]
protocol/bc/types/bytom/tx_status_test.go [deleted file]
protocol/bc/types/bytom/txheader.go [deleted file]
protocol/bc/types/bytom/types/block_commitment.go
protocol/bc/types/bytom/types/block_header.go
protocol/bc/types/bytom/types/issuance.go [deleted file]
protocol/bc/types/bytom/types/map.go
protocol/bc/types/bytom/types/merkle.go [deleted file]
protocol/bc/types/bytom/types/output_commitment.go
protocol/bc/types/bytom/types/spend.go
protocol/bc/types/bytom/types/spend_commitment.go
protocol/bc/types/bytom/types/transaction.go
protocol/bc/types/bytom/types/txinput.go
protocol/bc/types/bytom/types/txoutput.go
protocol/tx.go
protocol/txpool.go
protocol/validation/tx.go
tools/monitor_tx/http_client.go [new file with mode: 0644]
tools/monitor_tx/main.go [new file with mode: 0644]
tools/monitor_tx/ws_client.go [new file with mode: 0644]
tools/side_chain_tool/app/api/Connection.py
tools/side_chain_tool/app/api/transaction.py
tools/side_chain_tool/app/models.py
tools/side_chain_tool/sidechain.sh

index 503939b..427b042 100644 (file)
@@ -2,6 +2,7 @@
 package account
 
 import (
+       "encoding/hex"
        "encoding/json"
        "reflect"
        "sort"
@@ -20,6 +21,7 @@ import (
        "github.com/vapor/crypto"
        "github.com/vapor/crypto/ed25519/chainkd"
        "github.com/vapor/crypto/sha3pool"
+       "github.com/vapor/equity/pegin_contract"
        "github.com/vapor/errors"
        "github.com/vapor/protocol"
        "github.com/vapor/protocol/bc"
@@ -788,7 +790,10 @@ func (m *Manager) SaveControlPrograms(progs ...*CtrlProgram) error {
 
 func (m *Manager) CreatePeginAddress(accountID string, change bool) (string, []byte, error) {
        // 通过配置获取
-       claimCtrlProg, _ := m.CreateAddress(accountID, change)
+       claimCtrlProg, err := m.CreateAddress(accountID, change)
+       if err != nil {
+               return "", nil, err
+       }
        claimScript := claimCtrlProg.ControlProgram
 
        federationRedeemScript := vmutil.CalculateContract(consensus.ActiveNetParams.FedpegXPubs, claimScript)
@@ -808,7 +813,79 @@ func (m *Manager) GetPeginControlPrograms(claimScript []byte) (string, []byte) {
        federationRedeemScript := vmutil.CalculateContract(consensus.ActiveNetParams.FedpegXPubs, claimScript)
        scriptHash := crypto.Sha256(federationRedeemScript)
 
-       address, err := common.NewAddressWitnessScriptHash(scriptHash, &consensus.ActiveNetParams)
+       address, err := common.NewPeginAddressWitnessScriptHash(scriptHash, &consensus.ActiveNetParams)
+       if err != nil {
+               return "", nil
+       }
+
+       redeemContract := address.ScriptAddress()
+
+       program := []byte{}
+       program, err = vmutil.P2WSHProgram(redeemContract)
+       if err != nil {
+               return "", nil
+       }
+
+       return address.EncodeAddress(), program
+}
+
+func (m *Manager) CreatePeginContractPrograms(accountID string, change bool) (string, []byte, error) {
+       // 通过配置获取
+       claimCtrlProg, err := m.CreateAddress(accountID, change)
+       if err != nil {
+               return "", nil, err
+       }
+       claimScript := claimCtrlProg.ControlProgram
+
+       peginContractPrograms, err := pegin_contract.GetPeginContractPrograms(claimScript)
+       if err != nil {
+               return "", nil, err
+       }
+       return hex.EncodeToString(peginContractPrograms), claimScript, nil
+
+}
+
+func (m *Manager) CreatePeginContractAddress(accountID string, change bool) (string, []byte, []byte, error) {
+       // 通过配置获取
+       claimCtrlProg, err := m.CreateAddress(accountID, change)
+       if err != nil {
+               return "", nil, nil, err
+       }
+       claimScript := claimCtrlProg.ControlProgram
+
+       peginContractPrograms, err := pegin_contract.GetPeginContractPrograms(claimScript)
+       if err != nil {
+               return "", nil, nil, err
+       }
+
+       scriptHash := crypto.Sha256(peginContractPrograms)
+
+       address, err := common.NewPeginAddressWitnessScriptHash(scriptHash, &consensus.ActiveNetParams)
+       if err != nil {
+               return "", nil, nil, err
+       }
+
+       redeemContract := address.ScriptAddress()
+
+       program := []byte{}
+       program, err = vmutil.P2WSHProgram(redeemContract)
+       if err != nil {
+               return "", nil, nil, err
+       }
+
+       return address.EncodeAddress(), program, claimScript, nil
+
+}
+
+func (m *Manager) GetPeginContractControlPrograms(claimScript []byte) (string, []byte) {
+
+       peginContractPrograms, err := pegin_contract.GetPeginContractPrograms(claimScript)
+       if err != nil {
+               return "", nil
+       }
+       scriptHash := crypto.Sha256(peginContractPrograms)
+
+       address, err := common.NewPeginAddressWitnessScriptHash(scriptHash, &consensus.ActiveNetParams)
        if err != nil {
                return "", nil
        }
index 940d6d2..b8cbcfb 100644 (file)
@@ -248,11 +248,12 @@ func (a *API) buildHandler() {
                m.Handle("/recovery-wallet", jsonHandler(a.recoveryFromRootXPubs))
 
                m.Handle("/get-pegin-address", jsonHandler(a.getPeginAddress))
-               m.Handle("/claim-pegin-transaction", jsonHandler(a.claimPeginTx))
+               m.Handle("/get-pegin-contract-address", jsonHandler(a.getPeginContractAddress))
+               m.Handle("/claim-pegin-transaction", jsonHandler(a.claimContractPeginTx))
                m.Handle("/create-key-pair", jsonHandler(a.createXKeys))
                m.Handle("/get-utxo-from-transaction", jsonHandler(a.getUnspentOutputs))
                m.Handle("/get-side-raw-transaction", jsonHandler(a.getSideRawTransaction))
-               m.Handle("/build-mainchain-tx", jsonHandler(a.buildMainChainTx))
+               m.Handle("/build-mainchain-tx", jsonHandler(a.buildMainChainTxForContract))
                m.Handle("/sign-with-key", jsonHandler(a.signWithKey))
        } else {
                log.Warn("Please enable wallet")
diff --git a/api/cliam_transact.go b/api/cliam_transact.go
new file mode 100644 (file)
index 0000000..c19fce0
--- /dev/null
@@ -0,0 +1,385 @@
+package api
+
+import (
+       "bytes"
+       "context"
+       "encoding/json"
+       "strconv"
+       "time"
+
+       log "github.com/sirupsen/logrus"
+       "github.com/vapor/account"
+       "github.com/vapor/blockchain/txbuilder"
+       "github.com/vapor/consensus"
+       "github.com/vapor/crypto/sha3pool"
+       chainjson "github.com/vapor/encoding/json"
+       "github.com/vapor/errors"
+       "github.com/vapor/protocol/bc"
+       "github.com/vapor/protocol/bc/types"
+       bytomtypes "github.com/vapor/protocol/bc/types/bytom/types"
+       "github.com/vapor/protocol/validation"
+       "github.com/vapor/util"
+)
+
+func getPeginTxnOutputIndex(rawTx bytomtypes.Tx, controlProg []byte) int {
+       for index, output := range rawTx.Outputs {
+               if bytes.Equal(output.ControlProgram, controlProg) {
+                       return index
+               }
+       }
+       return -1
+}
+
+func toHash(hexBytes []chainjson.HexBytes) (hashs []*bc.Hash) {
+       for _, data := range hexBytes {
+               b32 := [32]byte{}
+               copy(b32[:], data)
+               res := bc.NewHash(b32)
+               hashs = append(hashs, &res)
+       }
+       return
+}
+
+func (a *API) claimPeginTx(ctx context.Context, ins struct {
+       Password     string                 `json:"password"`
+       RawTx        bytomtypes.Tx          `json:"raw_transaction"`
+       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
+       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
+       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
+       Flags        []uint32               `json:"flags"`
+       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
+       ClaimScript  chainjson.HexBytes     `json:"claim_script"`
+}) Response {
+       tmpl, err := a.createRawPegin(ctx, ins)
+       if err != nil {
+               log.WithField("build err", err).Error("fail on createrawpegin.")
+               return NewErrorResponse(err)
+       }
+       // 交易签名
+       if err := txbuilder.Sign(ctx, tmpl, ins.Password, a.PseudohsmSignTemplate); err != nil {
+               log.WithField("build err", err).Error("fail on sign transaction.")
+               return NewErrorResponse(err)
+       }
+
+       // submit
+       if err := txbuilder.FinalizeTx(ctx, a.chain, tmpl.Transaction); err != nil {
+               return NewErrorResponse(err)
+       }
+
+       log.WithField("tx_id", tmpl.Transaction.ID.String()).Info("claim script tx")
+       return NewSuccessResponse(&submitTxResp{TxID: &tmpl.Transaction.ID})
+}
+
+func (a *API) createRawPegin(ctx context.Context, ins struct {
+       Password     string                 `json:"password"`
+       RawTx        bytomtypes.Tx          `json:"raw_transaction"`
+       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
+       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
+       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
+       Flags        []uint32               `json:"flags"`
+       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
+       ClaimScript  chainjson.HexBytes     `json:"claim_script"`
+}) (*txbuilder.Template, error) {
+       // proof验证
+       var flags []uint8
+       for flag := range ins.Flags {
+               flags = append(flags, uint8(flag))
+       }
+       txHashes := toHash(ins.TxHashes)
+       matchedTxIDs := toHash(ins.MatchedTxIDs)
+       statusHashes := toHash(ins.StatusHashes)
+       if !types.ValidateTxMerkleTreeProof(txHashes, flags, matchedTxIDs, ins.BlockHeader.BlockCommitment.TransactionsMerkleRoot) {
+               return nil, errors.New("Merkleblock validation failed")
+       }
+       // CheckBytomProof
+       //difficulty.CheckBytomProofOfWork(ins.BlockHeader.Hash(), ins.BlockHeader)
+       // 增加spv验证以及连接主链api查询交易的确认数
+       if util.ValidatePegin {
+               if err := util.IsConfirmedBytomBlock(ins.BlockHeader.Height, consensus.ActiveNetParams.PeginMinDepth); err != nil {
+                       return nil, err
+               }
+       }
+       // 找出与claim script有关联的交易的输出
+       var claimScript []byte
+       nOut := len(ins.RawTx.Outputs)
+       if ins.ClaimScript == nil {
+               // 遍历寻找与交易输出有关的claim script
+               cps, err := a.wallet.AccountMgr.ListControlProgram()
+               if err != nil {
+                       return nil, err
+               }
+
+               for _, cp := range cps {
+                       _, controlProg := a.wallet.AccountMgr.GetPeginControlPrograms(cp.ControlProgram)
+                       if controlProg == nil {
+                               continue
+                       }
+                       // 获取交易的输出
+                       nOut = getPeginTxnOutputIndex(ins.RawTx, controlProg)
+                       if nOut != len(ins.RawTx.Outputs) {
+                               claimScript = cp.ControlProgram
+                       }
+               }
+       } else {
+               claimScript = ins.ClaimScript
+               _, controlProg := a.wallet.AccountMgr.GetPeginControlPrograms(claimScript)
+               // 获取交易的输出
+               nOut = getPeginTxnOutputIndex(ins.RawTx, controlProg)
+       }
+       if nOut == len(ins.RawTx.Outputs) || nOut == -1 {
+               return nil, errors.New("Failed to find output in bytom to the mainchain_address from getpeginaddress")
+       }
+
+       // 根据ClaimScript 获取account id
+       var hash [32]byte
+       sha3pool.Sum256(hash[:], claimScript)
+       data := a.wallet.DB.Get(account.ContractKey(hash))
+       if data == nil {
+               return nil, errors.New("Failed to find control program through claim script")
+       }
+
+       cp := &account.CtrlProgram{}
+       if err := json.Unmarshal(data, cp); err != nil {
+               return nil, errors.New("Failed on unmarshal control program")
+       }
+
+       // 构造交易
+       // 用输出作为交易输入 生成新的交易
+       builder := txbuilder.NewBuilder(time.Now())
+       // TODO 根据raw tx生成一个utxo
+       //txInput := types.NewClaimInputInput(nil, *ins.RawTx.Outputs[nOut].AssetId, ins.RawTx.Outputs[nOut].Amount, cp.ControlProgram)
+       sourceID := *ins.RawTx.OutputID(nOut)
+       outputAccount := ins.RawTx.Outputs[nOut].Amount
+       assetID := *ins.RawTx.Outputs[nOut].AssetId
+
+       txInput := types.NewClaimInputInput(nil, sourceID, assetID, outputAccount, uint64(nOut), cp.ControlProgram)
+       if err := builder.AddInput(txInput, &txbuilder.SigningInstruction{}); err != nil {
+               return nil, err
+       }
+       program, err := a.wallet.AccountMgr.CreateAddress(cp.AccountID, false)
+       if err != nil {
+               return nil, err
+       }
+
+       if err = builder.AddOutput(types.NewTxOutput(assetID, outputAccount, program.ControlProgram)); err != nil {
+               return nil, err
+       }
+
+       tmpl, txData, err := builder.Build()
+       if err != nil {
+               return nil, err
+       }
+
+       // todo把一些主链的信息加到交易的stack中
+       var stack [][]byte
+
+       //amount
+       amount := strconv.FormatUint(ins.RawTx.Outputs[nOut].Amount, 10)
+       stack = append(stack, []byte(amount))
+       // 主链的gennesisBlockHash
+       stack = append(stack, []byte(consensus.ActiveNetParams.ParentGenesisBlockHash))
+       // claim script
+       stack = append(stack, claimScript)
+       // raw tx
+       tx, _ := json.Marshal(ins.RawTx)
+       stack = append(stack, tx)
+       // proof
+       blockHeader, err := ins.BlockHeader.MarshalText()
+       if err != nil {
+               return nil, err
+       }
+       merkleBlock := validation.MerkleBlock{
+               BlockHeader:  blockHeader,
+               TxHashes:     txHashes,
+               StatusHashes: statusHashes,
+               Flags:        ins.Flags,
+               MatchedTxIDs: matchedTxIDs,
+       }
+
+       txOutProof, _ := json.Marshal(merkleBlock)
+
+       stack = append(stack, txOutProof)
+
+       //      tmpl.Transaction.Inputs[0].Peginwitness = stack
+       txData.Inputs[0].Peginwitness = stack
+
+       //交易费估算
+       txGasResp, err := EstimateTxGas(*tmpl)
+       if err != nil {
+               return nil, err
+       }
+       txData.Outputs[0].Amount = txData.Outputs[0].Amount - uint64(txGasResp.TotalNeu)
+       //重设置Transaction
+       tmpl.Transaction = types.NewTx(*txData)
+       return tmpl, nil
+}
+
+func (a *API) claimContractPeginTx(ctx context.Context, ins struct {
+       Password     string                 `json:"password"`
+       RawTx        bytomtypes.Tx          `json:"raw_transaction"`
+       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
+       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
+       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
+       Flags        []uint32               `json:"flags"`
+       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
+       ClaimScript  chainjson.HexBytes     `json:"claim_script"`
+}) Response {
+       tmpl, err := a.createContractRawPegin(ctx, ins)
+       if err != nil {
+               log.WithField("build err", err).Error("fail on claimContractPeginTx.")
+               return NewErrorResponse(err)
+       }
+       // 交易签名
+       if err := txbuilder.Sign(ctx, tmpl, ins.Password, a.PseudohsmSignTemplate); err != nil {
+               log.WithField("build err", err).Error("fail on sign transaction.")
+               return NewErrorResponse(err)
+       }
+
+       // submit
+       if err := txbuilder.FinalizeTx(ctx, a.chain, tmpl.Transaction); err != nil {
+               return NewErrorResponse(err)
+       }
+
+       log.WithField("tx_id", tmpl.Transaction.ID.String()).Info("claim script tx")
+       return NewSuccessResponse(&submitTxResp{TxID: &tmpl.Transaction.ID})
+}
+
+func (a *API) createContractRawPegin(ctx context.Context, ins struct {
+       Password     string                 `json:"password"`
+       RawTx        bytomtypes.Tx          `json:"raw_transaction"`
+       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
+       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
+       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
+       Flags        []uint32               `json:"flags"`
+       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
+       ClaimScript  chainjson.HexBytes     `json:"claim_script"`
+}) (*txbuilder.Template, error) {
+       // proof验证
+       var flags []uint8
+       for flag := range ins.Flags {
+               flags = append(flags, uint8(flag))
+       }
+       txHashes := toHash(ins.TxHashes)
+       matchedTxIDs := toHash(ins.MatchedTxIDs)
+       statusHashes := toHash(ins.StatusHashes)
+       if !types.ValidateTxMerkleTreeProof(txHashes, flags, matchedTxIDs, ins.BlockHeader.BlockCommitment.TransactionsMerkleRoot) {
+               return nil, errors.New("Merkleblock validation failed")
+       }
+       // CheckBytomProof
+       //difficulty.CheckBytomProofOfWork(ins.BlockHeader.Hash(), ins.BlockHeader)
+       // 增加spv验证以及连接主链api查询交易的确认数
+       if util.ValidatePegin {
+               if err := util.IsConfirmedBytomBlock(ins.BlockHeader.Height, consensus.ActiveNetParams.PeginMinDepth); err != nil {
+                       return nil, err
+               }
+       }
+       // 找出与claim script有关联的交易的输出
+       var claimScript []byte
+       nOut := len(ins.RawTx.Outputs)
+       if ins.ClaimScript == nil {
+               // 遍历寻找与交易输出有关的claim script
+               cps, err := a.wallet.AccountMgr.ListControlProgram()
+               if err != nil {
+                       return nil, err
+               }
+
+               for _, cp := range cps {
+                       _, controlProg := a.wallet.AccountMgr.GetPeginContractControlPrograms(claimScript)
+                       // 获取交易的输出
+                       nOut = getPeginTxnOutputIndex(ins.RawTx, controlProg)
+                       if nOut != len(ins.RawTx.Outputs) {
+                               claimScript = cp.ControlProgram
+                       }
+               }
+       } else {
+               claimScript = ins.ClaimScript
+               _, controlProg := a.wallet.AccountMgr.GetPeginContractControlPrograms(claimScript)
+               // 获取交易的输出
+               nOut = getPeginTxnOutputIndex(ins.RawTx, controlProg)
+       }
+       if nOut == len(ins.RawTx.Outputs) || nOut == -1 {
+               return nil, errors.New("Failed to find output in bytom to the mainchain_address from createContractRawPegin")
+       }
+
+       // 根据ClaimScript 获取account id
+       var hash [32]byte
+       sha3pool.Sum256(hash[:], claimScript)
+       data := a.wallet.DB.Get(account.ContractKey(hash))
+       if data == nil {
+               return nil, errors.New("Failed to find control program through claim script")
+       }
+
+       cp := &account.CtrlProgram{}
+       if err := json.Unmarshal(data, cp); err != nil {
+               return nil, errors.New("Failed on unmarshal control program")
+       }
+
+       // 构造交易
+       // 用输出作为交易输入 生成新的交易
+       builder := txbuilder.NewBuilder(time.Now())
+       // TODO 根据raw tx生成一个utxo
+       //txInput := types.NewClaimInputInput(nil, *ins.RawTx.Outputs[nOut].AssetId, ins.RawTx.Outputs[nOut].Amount, cp.ControlProgram)
+
+       sourceID := *ins.RawTx.OutputID(nOut)
+       outputAccount := ins.RawTx.Outputs[nOut].Amount
+       assetID := *ins.RawTx.Outputs[nOut].AssetId
+
+       txInput := types.NewClaimInputInput(nil, sourceID, assetID, outputAccount, uint64(nOut), cp.ControlProgram)
+       if err := builder.AddInput(txInput, &txbuilder.SigningInstruction{}); err != nil {
+               return nil, err
+       }
+       program, err := a.wallet.AccountMgr.CreateAddress(cp.AccountID, false)
+       if err != nil {
+               return nil, err
+       }
+
+       if err = builder.AddOutput(types.NewTxOutput(assetID, outputAccount, program.ControlProgram)); err != nil {
+               return nil, err
+       }
+
+       tmpl, txData, err := builder.Build()
+       if err != nil {
+               return nil, err
+       }
+
+       // todo把一些主链的信息加到交易的stack中
+       var stack [][]byte
+
+       //amount
+       amount := strconv.FormatUint(ins.RawTx.Outputs[nOut].Amount, 10)
+       stack = append(stack, []byte(amount))
+       // 主链的gennesisBlockHash
+       stack = append(stack, []byte(consensus.ActiveNetParams.ParentGenesisBlockHash))
+       // claim script
+       stack = append(stack, claimScript)
+       // raw tx
+       tx, _ := ins.RawTx.MarshalText()
+       //tx, _ := json.Marshal(ins.RawTx)
+       stack = append(stack, tx)
+       // proof
+       blockHeader, err := ins.BlockHeader.MarshalText()
+       if err != nil {
+               return nil, err
+       }
+       merkleBlock := validation.MerkleBlock{
+               BlockHeader:  blockHeader,
+               TxHashes:     txHashes,
+               StatusHashes: statusHashes,
+               Flags:        ins.Flags,
+               MatchedTxIDs: matchedTxIDs,
+       }
+       txOutProof, _ := json.Marshal(merkleBlock)
+       stack = append(stack, txOutProof)
+       //      tmpl.Transaction.Inputs[0].Peginwitness = stack
+       txData.Inputs[0].Peginwitness = stack
+
+       //交易费估算
+       txGasResp, err := EstimateTxGas(*tmpl)
+       if err != nil {
+               return nil, err
+       }
+       txData.Outputs[0].Amount = txData.Outputs[0].Amount - uint64(txGasResp.TotalNeu)
+       //重设置Transaction
+       tmpl.Transaction = types.NewTx(*txData)
+       return tmpl, nil
+}
diff --git a/api/main_transact.go b/api/main_transact.go
new file mode 100644 (file)
index 0000000..4bb63c8
--- /dev/null
@@ -0,0 +1,328 @@
+package api
+
+import (
+       "bytes"
+       "crypto/hmac"
+       "crypto/sha256"
+       "time"
+
+       log "github.com/sirupsen/logrus"
+
+       "github.com/vapor/account"
+       "github.com/vapor/blockchain/txbuilder"
+       "github.com/vapor/blockchain/txbuilder/mainchain"
+       "github.com/vapor/common"
+       "github.com/vapor/consensus"
+       "github.com/vapor/crypto/ed25519/chainkd"
+       chainjson "github.com/vapor/encoding/json"
+       "github.com/vapor/equity/pegin_contract"
+       "github.com/vapor/errors"
+       "github.com/vapor/protocol/bc"
+       "github.com/vapor/protocol/bc/types"
+       bytomtypes "github.com/vapor/protocol/bc/types/bytom/types"
+       "github.com/vapor/protocol/vm/vmutil"
+)
+
+func (a *API) buildMainChainTxForContract(ins struct {
+       Utxo           account.UTXO       `json:"utxo"`
+       Tx             types.Tx           `json:"raw_transaction"`
+       RootXPubs      []chainkd.XPub     `json:"root_xpubs"`
+       ControlProgram string             `json:"control_program"`
+       ClaimScript    chainjson.HexBytes `json:"claim_script"`
+}) Response {
+
+       var xpubs []chainkd.XPub
+       for _, xpub := range ins.RootXPubs {
+               // pub + scriptPubKey 生成一个随机数A
+               var tmp [32]byte
+               h := hmac.New(sha256.New, xpub[:])
+               h.Write(ins.ClaimScript)
+               tweak := h.Sum(tmp[:])
+               // pub +  A 生成一个新的公钥pub_new
+               chaildXPub := xpub.Child(tweak)
+               xpubs = append(xpubs, chaildXPub)
+       }
+
+       txInput, sigInst, err := contractToInputs(a, &ins.Utxo, xpubs, ins.ClaimScript)
+       builder := mainchain.NewBuilder(time.Now())
+       builder.AddInput(txInput, sigInst)
+       changeAmount := uint64(0)
+       retire := false
+       for _, key := range ins.Tx.GetResultIds() {
+               output, err := ins.Tx.Retire(*key)
+               if err != nil {
+                       log.WithFields(log.Fields{"moudle": "transact", "err": err}).Warn("buildMainChainTx error")
+                       continue
+               }
+               retire = true
+               var controlProgram []byte
+               retBool := true
+               if controlProgram, retBool = getInput(ins.Tx.Entries, *key, ins.ControlProgram); !retBool {
+                       return NewErrorResponse(errors.New("The corresponding input cannot be found"))
+               }
+
+               assetID := *output.Source.Value.AssetId
+               out := bytomtypes.NewTxOutput(assetID, output.Source.Value.Amount, controlProgram)
+               builder.AddOutput(out)
+               changeAmount = ins.Utxo.Amount - output.Source.Value.Amount
+
+       }
+
+       if !retire {
+               return NewErrorResponse(errors.New("It's not a transaction to retire assets"))
+       }
+
+       if changeAmount > 0 {
+               u := ins.Utxo
+               out := bytomtypes.NewTxOutput(u.AssetID, changeAmount, ins.Utxo.ControlProgram)
+               builder.AddOutput(out)
+       }
+
+       tmpl, tx, err := builder.Build()
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       for i, out := range tmpl.Transaction.Outputs {
+               if bytes.Equal(out.ControlProgram, ins.Utxo.ControlProgram) {
+                       //tx.Outputs[i].Amount = changeAmount - uint64(txGasResp.TotalNeu)
+                       tx.Outputs[i].Amount = changeAmount - 100000000
+               }
+       }
+       tmpl.Transaction = bytomtypes.NewTx(*tx)
+       return NewSuccessResponse(tmpl)
+}
+
+func (a *API) buildMainChainTx(ins struct {
+       Utxo           account.UTXO       `json:"utxo"`
+       Tx             types.Tx           `json:"raw_transaction"`
+       RootXPubs      []chainkd.XPub     `json:"root_xpubs"`
+       ControlProgram string             `json:"control_program"`
+       ClaimScript    chainjson.HexBytes `json:"claim_script"`
+}) Response {
+
+       var xpubs []chainkd.XPub
+       for _, xpub := range ins.RootXPubs {
+               // pub + scriptPubKey 生成一个随机数A
+               var tmp [32]byte
+               h := hmac.New(sha256.New, xpub[:])
+               h.Write(ins.ClaimScript)
+               tweak := h.Sum(tmp[:])
+               // pub +  A 生成一个新的公钥pub_new
+               chaildXPub := xpub.Child(tweak)
+               xpubs = append(xpubs, chaildXPub)
+       }
+
+       txInput, sigInst, err := utxoToInputs(xpubs, &ins.Utxo)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       builder := mainchain.NewBuilder(time.Now())
+       builder.AddInput(txInput, sigInst)
+       changeAmount := uint64(0)
+       retire := false
+       for _, key := range ins.Tx.GetResultIds() {
+               output, err := ins.Tx.Retire(*key)
+               if err != nil {
+                       log.WithFields(log.Fields{"moudle": "transact", "err": err}).Warn("buildMainChainTx error")
+                       continue
+               }
+               retire = true
+               var controlProgram []byte
+               retBool := true
+               if controlProgram, retBool = getInput(ins.Tx.Entries, *key, ins.ControlProgram); !retBool {
+                       return NewErrorResponse(errors.New("The corresponding input cannot be found"))
+               }
+
+               assetID := *output.Source.Value.AssetId
+               out := bytomtypes.NewTxOutput(assetID, output.Source.Value.Amount, controlProgram)
+               builder.AddOutput(out)
+               changeAmount = ins.Utxo.Amount - output.Source.Value.Amount
+
+       }
+
+       if !retire {
+               return NewErrorResponse(errors.New("It's not a transaction to retire assets"))
+       }
+
+       if changeAmount > 0 {
+               u := ins.Utxo
+               out := bytomtypes.NewTxOutput(u.AssetID, changeAmount, ins.Utxo.ControlProgram)
+               builder.AddOutput(out)
+       }
+
+       tmpl, tx, err := builder.Build()
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+       //交易费估算
+       txGasResp, err := EstimateTxGasForMainchain(*tmpl)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+       for i, out := range tmpl.Transaction.Outputs {
+               if bytes.Equal(out.ControlProgram, ins.Utxo.ControlProgram) {
+                       tx.Outputs[i].Amount = changeAmount - uint64(txGasResp.TotalNeu)
+               }
+       }
+       tmpl.Transaction = bytomtypes.NewTx(*tx)
+       return NewSuccessResponse(tmpl)
+}
+
+//
+func getInput(entry map[bc.Hash]bc.Entry, outputID bc.Hash, controlProgram string) ([]byte, bool) {
+       output := entry[outputID].(*bc.Retirement)
+       mux := entry[*output.Source.Ref].(*bc.Mux)
+
+       for _, valueSource := range mux.GetSources() {
+               spend := entry[*valueSource.Ref].(*bc.Spend)
+               prevout := entry[*spend.SpentOutputId].(*bc.Output)
+
+               var ctrlProgram chainjson.HexBytes
+               ctrlProgram = prevout.ControlProgram.Code
+               tmp, _ := ctrlProgram.MarshalText()
+               if string(tmp) == controlProgram {
+                       return ctrlProgram, true
+               }
+       }
+       return nil, false
+}
+
+// UtxoToInputs convert an utxo to the txinput
+func utxoToInputs(xpubs []chainkd.XPub, u *account.UTXO) (*bytomtypes.TxInput, *mainchain.SigningInstruction, error) {
+       txInput := bytomtypes.NewSpendInput(nil, u.SourceID, u.AssetID, u.Amount, u.SourcePos, u.ControlProgram)
+       sigInst := &mainchain.SigningInstruction{}
+       quorum := len(xpubs)
+       if u.Address == "" {
+               sigInst.AddWitnessKeys(xpubs, quorum)
+               return txInput, sigInst, nil
+       }
+
+       address, err := common.DecodeBytomAddress(u.Address, &consensus.ActiveNetParams)
+       if err != nil {
+               return nil, nil, err
+       }
+
+       sigInst.AddRawWitnessKeysWithoutPath(xpubs, quorum)
+
+       switch address.(type) {
+       case *common.AddressWitnessPubKeyHash:
+               derivedPK := xpubs[0].PublicKey()
+               sigInst.WitnessComponents = append(sigInst.WitnessComponents, mainchain.DataWitness([]byte(derivedPK)))
+
+       case *common.AddressWitnessScriptHash:
+               derivedXPubs := xpubs
+               derivedPKs := chainkd.XPubKeys(derivedXPubs)
+               script, err := vmutil.P2SPMultiSigProgram(derivedPKs, quorum)
+               if err != nil {
+                       return nil, nil, err
+               }
+               sigInst.WitnessComponents = append(sigInst.WitnessComponents, mainchain.DataWitness(script))
+
+       default:
+               return nil, nil, errors.New("unsupport address type")
+       }
+
+       return txInput, sigInst, nil
+}
+
+func contractToInputs(a *API, u *account.UTXO, xpubs []chainkd.XPub, ClaimScript chainjson.HexBytes) (*bytomtypes.TxInput, *mainchain.SigningInstruction, error) {
+       txInput := bytomtypes.NewSpendInput(nil, u.SourceID, u.AssetID, u.Amount, u.SourcePos, u.ControlProgram)
+       sigInst := &mainchain.SigningInstruction{}
+
+       // raw_tx_signature
+       for _, xpub := range xpubs {
+               xpubsTmp := []chainkd.XPub{xpub}
+               sigInst.AddRawWitnessKeysWithoutPath(xpubsTmp, 1)
+       }
+
+       // data
+       peginContractPrograms, err := pegin_contract.GetPeginContractPrograms(ClaimScript)
+       if err != nil {
+               return nil, nil, err
+       }
+       sigInst.WitnessComponents = append(sigInst.WitnessComponents, mainchain.DataWitness(peginContractPrograms))
+
+       return txInput, sigInst, nil
+}
+
+type signRespForMainchain struct {
+       Tx           *mainchain.Template `json:"transaction"`
+       SignComplete bool                `json:"sign_complete"`
+}
+
+func (a *API) signWithKey(ins struct {
+       Xprv        string             `json:"xprv"`
+       XPub        chainkd.XPub       `json:"xpub"`
+       Txs         mainchain.Template `json:"transaction"`
+       ClaimScript chainjson.HexBytes `json:"claim_script"`
+}) Response {
+       xprv := &chainkd.XPrv{}
+       if err := xprv.UnmarshalText([]byte(ins.Xprv)); err != nil {
+               return NewErrorResponse(err)
+       }
+       // pub + scriptPubKey 生成一个随机数A
+       var tmp [32]byte
+       h := hmac.New(sha256.New, ins.XPub[:])
+       h.Write(ins.ClaimScript)
+       tweak := h.Sum(tmp[:])
+       // pub +  A 生成一个新的公钥pub_new
+       privateKey := xprv.Child(tweak, false)
+
+       if err := sign(&ins.Txs, privateKey); err != nil {
+               return NewErrorResponse(err)
+       }
+       log.Info("Sign Transaction complete.")
+       log.Info(mainchain.SignProgress(&ins.Txs))
+       return NewSuccessResponse(&signRespForMainchain{Tx: &ins.Txs, SignComplete: mainchain.SignProgress(&ins.Txs)})
+}
+
+func sign(tmpl *mainchain.Template, xprv chainkd.XPrv) error {
+       for i, sigInst := range tmpl.SigningInstructions {
+               for j, wc := range sigInst.WitnessComponents {
+                       switch sw := wc.(type) {
+                       case *mainchain.SignatureWitness:
+                               err := sw.Sign(tmpl, uint32(i), xprv)
+                               if err != nil {
+                                       return errors.WithDetailf(err, "adding signature(s) to signature witness component %d of input %d", j, i)
+                               }
+                       case *mainchain.RawTxSigWitness:
+                               err := sw.Sign(tmpl, uint32(i), xprv)
+                               if err != nil {
+                                       return errors.WithDetailf(err, "adding signature(s) to raw-signature witness component %d of input %d", j, i)
+                               }
+                       }
+               }
+       }
+       return materializeWitnesses(tmpl)
+}
+
+func materializeWitnesses(txTemplate *mainchain.Template) error {
+       msg := txTemplate.Transaction
+
+       if msg == nil {
+               return errors.Wrap(txbuilder.ErrMissingRawTx)
+       }
+
+       if len(txTemplate.SigningInstructions) > len(msg.Inputs) {
+               return errors.Wrap(txbuilder.ErrBadInstructionCount)
+       }
+
+       for i, sigInst := range txTemplate.SigningInstructions {
+               if msg.Inputs[sigInst.Position] == nil {
+                       return errors.WithDetailf(txbuilder.ErrBadTxInputIdx, "signing instruction %d references missing tx input %d", i, sigInst.Position)
+               }
+
+               var witness [][]byte
+               for j, wc := range sigInst.WitnessComponents {
+                       err := wc.Materialize(&witness)
+                       if err != nil {
+                               return errors.WithDetailf(err, "error in witness component %d of input %d", j, i)
+                       }
+               }
+               msg.SetInputArguments(sigInst.Position, witness)
+       }
+
+       return nil
+}
index c5b0842..79ab3a9 100644 (file)
@@ -7,7 +7,6 @@ import (
 
        "github.com/vapor/blockchain/txbuilder"
        "github.com/vapor/crypto/ed25519"
-       "github.com/vapor/protocol/bc/types/bytom"
 
        log "github.com/sirupsen/logrus"
 
@@ -415,7 +414,7 @@ func (a *API) listPubKeys(ctx context.Context, ins struct {
 
 type GetRawTransationResp struct {
        Tx        *bytomtypes.Tx `json:"raw_transaction"`
-       BlockHash bytom.Hash     `json:"block_hash"`
+       BlockHash bc.Hash        `json:"block_hash"`
 }
 
 func (a *API) getRawTransaction(ins struct {
@@ -432,7 +431,6 @@ func (a *API) getRawTransaction(ins struct {
 
        txID := bc.Hash{}
        txID.UnmarshalText([]byte(ins.TxID))
-
        for _, tx := range block.Transactions {
                if tx.ID.String() == txID.String() {
                        rawTransaction = tx
index 11408df..7ccffc0 100644 (file)
@@ -34,6 +34,7 @@ func (a *API) createAccountReceiver(ctx context.Context, ins struct {
 
 type fundingResp struct {
        MainchainAddress string             `json:"mainchain_address"`
+       ControlProgram   chainjson.HexBytes `json:"control_program,omitempty"`
        ClaimScript      chainjson.HexBytes `json:"claim_script"`
 }
 
@@ -62,3 +63,30 @@ func (a *API) getPeginAddress(ctx context.Context, ins struct {
                ClaimScript:      claimScript,
        })
 }
+
+func (a *API) getPeginContractAddress(ctx context.Context, ins struct {
+       AccountID    string `json:"account_id"`
+       AccountAlias string `json:"account_alias"`
+}) Response {
+
+       accountID := ins.AccountID
+       if ins.AccountAlias != "" {
+               account, err := a.wallet.AccountMgr.FindByAlias(ins.AccountAlias)
+               if err != nil {
+                       return NewErrorResponse(err)
+               }
+
+               accountID = account.ID
+       }
+
+       mainchainAddress, controlProgram, claimScript, err := a.wallet.AccountMgr.CreatePeginContractAddress(accountID, false)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
+       return NewSuccessResponse(fundingResp{
+               MainchainAddress: mainchainAddress,
+               ControlProgram:   controlProgram,
+               ClaimScript:      claimScript,
+       })
+}
index 7ab8f4d..1c0f274 100644 (file)
@@ -1,37 +1,23 @@
 package api
 
 import (
-       "bytes"
        "context"
-       "crypto/hmac"
-       "crypto/sha256"
        "encoding/json"
        "math"
-       "strconv"
        "strings"
        "time"
 
        log "github.com/sirupsen/logrus"
 
        "github.com/vapor/account"
-       "github.com/vapor/blockchain/signers"
        "github.com/vapor/blockchain/txbuilder"
-       "github.com/vapor/blockchain/txbuilder/mainchain"
-       "github.com/vapor/common"
        "github.com/vapor/consensus"
        "github.com/vapor/consensus/segwit"
-       "github.com/vapor/crypto/ed25519/chainkd"
-       "github.com/vapor/crypto/sha3pool"
-       chainjson "github.com/vapor/encoding/json"
        "github.com/vapor/errors"
        "github.com/vapor/math/checked"
        "github.com/vapor/net/http/reqid"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
-       "github.com/vapor/protocol/bc/types/bytom"
-       bytomtypes "github.com/vapor/protocol/bc/types/bytom/types"
-       "github.com/vapor/protocol/vm/vmutil"
-       "github.com/vapor/util"
 )
 
 var (
@@ -351,464 +337,3 @@ func (a *API) estimateTxGas(ctx context.Context, in struct {
        }
        return NewSuccessResponse(txGasResp)
 }
-
-func getPeginTxnOutputIndex(rawTx bytomtypes.Tx, controlProg []byte) int {
-       for index, output := range rawTx.Outputs {
-               if bytes.Equal(output.ControlProgram, controlProg) {
-                       return index
-               }
-       }
-       return 0
-}
-
-func toHash(hexBytes []chainjson.HexBytes) (hashs []*bytom.Hash) {
-       for _, data := range hexBytes {
-               b32 := [32]byte{}
-               copy(b32[:], data)
-               res := bytom.NewHash(b32)
-               hashs = append(hashs, &res)
-       }
-       return
-}
-
-func (a *API) claimPeginTx(ctx context.Context, ins struct {
-       Password     string                 `json:"password"`
-       RawTx        bytomtypes.Tx          `json:"raw_transaction"`
-       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
-       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
-       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
-       Flags        []uint32               `json:"flags"`
-       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
-       ClaimScript  chainjson.HexBytes     `json:"claim_script"`
-}) Response {
-       tmpl, err := a.createrawpegin(ctx, ins)
-       if err != nil {
-               log.WithField("build err", err).Error("fail on createrawpegin.")
-               return NewErrorResponse(err)
-       }
-       // 交易签名
-       if err := txbuilder.Sign(ctx, tmpl, ins.Password, a.PseudohsmSignTemplate); err != nil {
-               log.WithField("build err", err).Error("fail on sign transaction.")
-               return NewErrorResponse(err)
-       }
-
-       // submit
-       if err := txbuilder.FinalizeTx(ctx, a.chain, tmpl.Transaction); err != nil {
-               return NewErrorResponse(err)
-       }
-
-       log.WithField("tx_id", tmpl.Transaction.ID.String()).Info("claim script tx")
-       return NewSuccessResponse(&submitTxResp{TxID: &tmpl.Transaction.ID})
-}
-
-// GetMerkleBlockResp is resp struct for GetTxOutProof API
-type GetMerkleBlock struct {
-       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
-       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
-       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
-       Flags        []uint32               `json:"flags"`
-       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
-}
-
-func (a *API) createrawpegin(ctx context.Context, ins struct {
-       Password     string                 `json:"password"`
-       RawTx        bytomtypes.Tx          `json:"raw_transaction"`
-       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
-       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
-       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
-       Flags        []uint32               `json:"flags"`
-       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
-       ClaimScript  chainjson.HexBytes     `json:"claim_script"`
-}) (*txbuilder.Template, error) {
-       // proof验证
-       var flags []uint8
-       for flag := range ins.Flags {
-               flags = append(flags, uint8(flag))
-       }
-       txHashes := toHash(ins.TxHashes)
-       matchedTxIDs := toHash(ins.MatchedTxIDs)
-       if !bytomtypes.ValidateTxMerkleTreeProof(txHashes, flags, matchedTxIDs, ins.BlockHeader.BlockCommitment.TransactionsMerkleRoot) {
-               return nil, errors.New("Merkleblock validation failed")
-       }
-       // CheckBytomProof
-       //difficulty.CheckBytomProofOfWork(ins.BlockHeader.Hash(), ins.BlockHeader)
-       // 增加spv验证以及连接主链api查询交易的确认数
-       if util.ValidatePegin {
-               if err := util.IsConfirmedBytomBlock(ins.BlockHeader.Height, consensus.ActiveNetParams.PeginMinDepth); err != nil {
-                       return nil, err
-               }
-       }
-       // 找出与claim script有关联的交易的输出
-       var claimScript []byte
-       nOut := len(ins.RawTx.Outputs)
-       if ins.ClaimScript == nil {
-               // 遍历寻找与交易输出有关的claim script
-               cps, err := a.wallet.AccountMgr.ListControlProgram()
-               if err != nil {
-                       return nil, err
-               }
-
-               for _, cp := range cps {
-                       _, controlProg := a.wallet.AccountMgr.GetPeginControlPrograms(cp.ControlProgram)
-                       if controlProg == nil {
-                               continue
-                       }
-                       // 获取交易的输出
-                       nOut = getPeginTxnOutputIndex(ins.RawTx, controlProg)
-                       if nOut != len(ins.RawTx.Outputs) {
-                               claimScript = cp.ControlProgram
-                       }
-               }
-       } else {
-               claimScript = ins.ClaimScript
-               _, controlProg := a.wallet.AccountMgr.GetPeginControlPrograms(claimScript)
-               // 获取交易的输出
-               nOut = getPeginTxnOutputIndex(ins.RawTx, controlProg)
-       }
-       if nOut == len(ins.RawTx.Outputs) {
-               return nil, errors.New("Failed to find output in bytom to the mainchain_address from getpeginaddress")
-       }
-
-       // 根据ClaimScript 获取account id
-       var hash [32]byte
-       sha3pool.Sum256(hash[:], claimScript)
-       data := a.wallet.DB.Get(account.ContractKey(hash))
-       if data == nil {
-               return nil, errors.New("Failed to find control program through claim script")
-       }
-
-       cp := &account.CtrlProgram{}
-       if err := json.Unmarshal(data, cp); err != nil {
-               return nil, errors.New("Failed on unmarshal control program")
-       }
-
-       // 构造交易
-       // 用输出作为交易输入 生成新的交易
-       builder := txbuilder.NewBuilder(time.Now())
-       // TODO 根据raw tx生成一个utxo
-       //txInput := types.NewClaimInputInput(nil, *ins.RawTx.Outputs[nOut].AssetId, ins.RawTx.Outputs[nOut].Amount, cp.ControlProgram)
-       assetId := bc.AssetID{}
-       assetId.V0 = ins.RawTx.Outputs[nOut].AssetId.GetV0()
-       assetId.V1 = ins.RawTx.Outputs[nOut].AssetId.GetV1()
-       assetId.V2 = ins.RawTx.Outputs[nOut].AssetId.GetV2()
-       assetId.V3 = ins.RawTx.Outputs[nOut].AssetId.GetV3()
-
-       sourceID := bc.Hash{}
-       sourceID.V0 = ins.RawTx.OutputID(nOut).GetV0()
-       sourceID.V1 = ins.RawTx.OutputID(nOut).GetV1()
-       sourceID.V2 = ins.RawTx.OutputID(nOut).GetV2()
-       sourceID.V3 = ins.RawTx.OutputID(nOut).GetV3()
-       outputAccount := ins.RawTx.Outputs[nOut].Amount
-
-       txInput := types.NewClaimInputInput(nil, sourceID, assetId, outputAccount, uint64(nOut), cp.ControlProgram)
-       if err := builder.AddInput(txInput, &txbuilder.SigningInstruction{}); err != nil {
-               return nil, err
-       }
-       program, err := a.wallet.AccountMgr.CreateAddress(cp.AccountID, false)
-       if err != nil {
-               return nil, err
-       }
-
-       if err = builder.AddOutput(types.NewTxOutput(assetId, outputAccount, program.ControlProgram)); err != nil {
-               return nil, err
-       }
-
-       tmpl, txData, err := builder.Build()
-       if err != nil {
-               return nil, err
-       }
-
-       // todo把一些主链的信息加到交易的stack中
-       var stack [][]byte
-
-       //amount
-       amount := strconv.FormatUint(ins.RawTx.Outputs[nOut].Amount, 10)
-       stack = append(stack, []byte(amount))
-       // 主链的gennesisBlockHash
-       stack = append(stack, []byte(consensus.ActiveNetParams.ParentGenesisBlockHash))
-       // claim script
-       stack = append(stack, claimScript)
-       // raw tx
-       tx, _ := json.Marshal(ins.RawTx)
-       stack = append(stack, tx)
-       // proof
-       MerkleBLock := GetMerkleBlock{
-               BlockHeader:  ins.BlockHeader,
-               TxHashes:     ins.TxHashes,
-               StatusHashes: ins.StatusHashes,
-               Flags:        ins.Flags,
-               MatchedTxIDs: ins.MatchedTxIDs,
-       }
-       txOutProof, _ := json.Marshal(MerkleBLock)
-       stack = append(stack, txOutProof)
-
-       //      tmpl.Transaction.Inputs[0].Peginwitness = stack
-       txData.Inputs[0].Peginwitness = stack
-
-       //交易费估算
-       txGasResp, err := EstimateTxGas(*tmpl)
-       if err != nil {
-               return nil, err
-       }
-       txData.Outputs[0].Amount = txData.Outputs[0].Amount - uint64(txGasResp.TotalNeu)
-       //重设置Transaction
-       tmpl.Transaction = types.NewTx(*txData)
-       return tmpl, nil
-}
-
-func (a *API) buildMainChainTx(ins struct {
-       Utxo           account.UTXO       `json:"utxo"`
-       Tx             types.Tx           `json:"raw_transaction"`
-       RootXPubs      []chainkd.XPub     `json:"root_xpubs"`
-       Alias          string             `json:"alias"`
-       ControlProgram string             `json:"control_program"`
-       ClaimScript    chainjson.HexBytes `json:"claim_script"`
-}) Response {
-
-       var xpubs []chainkd.XPub
-       for _, xpub := range ins.RootXPubs {
-               // pub + scriptPubKey 生成一个随机数A
-               var tmp [32]byte
-               h := hmac.New(sha256.New, xpub[:])
-               h.Write(ins.ClaimScript)
-               tweak := h.Sum(tmp[:])
-               // pub +  A 生成一个新的公钥pub_new
-               chaildXPub := xpub.Child(tweak)
-               xpubs = append(xpubs, chaildXPub)
-       }
-       acc := &account.Account{}
-       var err error
-       if acc, err = a.wallet.AccountMgr.FindByAlias(ins.Alias); err != nil {
-               acc, err = a.wallet.AccountMgr.Create(xpubs, len(xpubs), ins.Alias, signers.BIP0044)
-               if err != nil {
-                       return NewErrorResponse(err)
-               }
-       }
-       ins.Utxo.ControlProgramIndex = acc.Signer.KeyIndex
-
-       txInput, sigInst, err := utxoToInputs(acc.Signer, &ins.Utxo)
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-
-       builder := mainchain.NewBuilder(time.Now())
-       builder.AddInput(txInput, sigInst)
-       changeAmount := uint64(0)
-       retire := false
-       for _, key := range ins.Tx.GetResultIds() {
-               output, err := ins.Tx.Retire(*key)
-               if err != nil {
-                       log.WithFields(log.Fields{"moudle": "transact", "err": err}).Warn("buildMainChainTx error")
-                       continue
-               }
-               retire = true
-               var controlProgram []byte
-               retBool := true
-               if controlProgram, retBool = getInput(ins.Tx.Entries, *key, ins.ControlProgram); !retBool {
-                       return NewErrorResponse(errors.New("The corresponding input cannot be found"))
-               }
-
-               assetID := bytom.AssetID{
-                       V0: output.Source.Value.AssetId.GetV0(),
-                       V1: output.Source.Value.AssetId.GetV1(),
-                       V2: output.Source.Value.AssetId.GetV2(),
-                       V3: output.Source.Value.AssetId.GetV3(),
-               }
-               out := bytomtypes.NewTxOutput(assetID, output.Source.Value.Amount, controlProgram)
-               builder.AddOutput(out)
-               changeAmount = ins.Utxo.Amount - output.Source.Value.Amount
-
-       }
-
-       if !retire {
-               return NewErrorResponse(errors.New("It's not a transaction to retire assets"))
-       }
-
-       if changeAmount > 0 {
-               u := ins.Utxo
-               assetID := bytom.AssetID{
-                       V0: u.AssetID.GetV0(),
-                       V1: u.AssetID.GetV1(),
-                       V2: u.AssetID.GetV2(),
-                       V3: u.AssetID.GetV3(),
-               }
-               out := bytomtypes.NewTxOutput(assetID, changeAmount, ins.Utxo.ControlProgram)
-               builder.AddOutput(out)
-       }
-
-       tmpl, tx, err := builder.Build()
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-       //交易费估算
-       txGasResp, err := EstimateTxGasForMainchain(*tmpl)
-       if err != nil {
-               return NewErrorResponse(err)
-       }
-       for i, out := range tmpl.Transaction.Outputs {
-               if bytes.Equal(out.ControlProgram, ins.Utxo.ControlProgram) {
-                       tx.Outputs[i].Amount = changeAmount - uint64(txGasResp.TotalNeu)
-               }
-       }
-       tmpl.Transaction = bytomtypes.NewTx(*tx)
-       return NewSuccessResponse(tmpl)
-}
-
-//
-func getInput(entry map[bc.Hash]bc.Entry, outputID bc.Hash, controlProgram string) ([]byte, bool) {
-       output := entry[outputID].(*bc.Retirement)
-       mux := entry[*output.Source.Ref].(*bc.Mux)
-
-       for _, valueSource := range mux.GetSources() {
-               spend := entry[*valueSource.Ref].(*bc.Spend)
-               prevout := entry[*spend.SpentOutputId].(*bc.Output)
-
-               var ctrlProgram chainjson.HexBytes
-               ctrlProgram = prevout.ControlProgram.Code
-               tmp, _ := ctrlProgram.MarshalText()
-               if string(tmp) == controlProgram {
-                       return ctrlProgram, true
-               }
-       }
-       return nil, false
-}
-
-// UtxoToInputs convert an utxo to the txinput
-func utxoToInputs(signer *signers.Signer, u *account.UTXO) (*bytomtypes.TxInput, *mainchain.SigningInstruction, error) {
-       sourceID := bytom.Hash{
-               V0: u.SourceID.GetV0(),
-               V1: u.SourceID.GetV1(),
-               V2: u.SourceID.GetV2(),
-               V3: u.SourceID.GetV3(),
-       }
-
-       assetID := bytom.AssetID{
-               V0: u.AssetID.GetV0(),
-               V1: u.AssetID.GetV1(),
-               V2: u.AssetID.GetV2(),
-               V3: u.AssetID.GetV3(),
-       }
-
-       txInput := bytomtypes.NewSpendInput(nil, sourceID, assetID, u.Amount, u.SourcePos, u.ControlProgram)
-       sigInst := &mainchain.SigningInstruction{}
-       if signer == nil {
-               return txInput, sigInst, nil
-       }
-
-       // TODO  u.Change看怎么填写
-       path, _ := signers.Path(signer, signers.AccountKeySpace, u.Change, u.ControlProgramIndex)
-       if u.Address == "" {
-               sigInst.AddWitnessKeys(signer.XPubs, path, signer.Quorum)
-               return txInput, sigInst, nil
-       }
-
-       address, err := common.DecodeBytomAddress(u.Address, &consensus.ActiveNetParams)
-       if err != nil {
-               return nil, nil, err
-       }
-
-       switch address.(type) {
-       case *common.AddressWitnessPubKeyHash:
-               sigInst.AddRawWitnessKeys(signer.XPubs, path, signer.Quorum)
-               derivedXPubs := chainkd.DeriveXPubs(signer.XPubs, path)
-               derivedPK := derivedXPubs[0].PublicKey()
-               sigInst.WitnessComponents = append(sigInst.WitnessComponents, mainchain.DataWitness([]byte(derivedPK)))
-
-       case *common.AddressWitnessScriptHash:
-               sigInst.AddRawWitnessKeys(signer.XPubs, path, signer.Quorum)
-               //path := signers.Path(signer, signers.AccountKeySpace, u.ControlProgramIndex)
-               //derivedXPubs := chainkd.DeriveXPubs(signer.XPubs, path)
-               derivedXPubs := signer.XPubs
-               derivedPKs := chainkd.XPubKeys(derivedXPubs)
-               script, err := vmutil.P2SPMultiSigProgram(derivedPKs, signer.Quorum)
-               if err != nil {
-                       return nil, nil, err
-               }
-               sigInst.WitnessComponents = append(sigInst.WitnessComponents, mainchain.DataWitness(script))
-
-       default:
-               return nil, nil, errors.New("unsupport address type")
-       }
-
-       return txInput, sigInst, nil
-}
-
-type signRespForMainchain struct {
-       Tx           *mainchain.Template `json:"transaction"`
-       SignComplete bool                `json:"sign_complete"`
-}
-
-func (a *API) signWithKey(ins struct {
-       Xprv        string             `json:"xprv"`
-       XPub        chainkd.XPub       `json:"xpub"`
-       Txs         mainchain.Template `json:"transaction"`
-       ClaimScript chainjson.HexBytes `json:"claim_script"`
-}) Response {
-       xprv := &chainkd.XPrv{}
-       if err := xprv.UnmarshalText([]byte(ins.Xprv)); err != nil {
-               return NewErrorResponse(err)
-       }
-       // pub + scriptPubKey 生成一个随机数A
-       var tmp [32]byte
-       h := hmac.New(sha256.New, ins.XPub[:])
-       h.Write(ins.ClaimScript)
-       tweak := h.Sum(tmp[:])
-       // pub +  A 生成一个新的公钥pub_new
-       privateKey := xprv.Child(tweak, false)
-
-       if err := sign(&ins.Txs, privateKey); err != nil {
-               return NewErrorResponse(err)
-       }
-       log.Info("Sign Transaction complete.")
-       log.Info(mainchain.SignProgress(&ins.Txs))
-       return NewSuccessResponse(&signRespForMainchain{Tx: &ins.Txs, SignComplete: mainchain.SignProgress(&ins.Txs)})
-}
-
-func sign(tmpl *mainchain.Template, xprv chainkd.XPrv) error {
-       for i, sigInst := range tmpl.SigningInstructions {
-               for j, wc := range sigInst.WitnessComponents {
-                       switch sw := wc.(type) {
-                       case *mainchain.SignatureWitness:
-                               err := sw.Sign(tmpl, uint32(i), xprv)
-                               if err != nil {
-                                       return errors.WithDetailf(err, "adding signature(s) to signature witness component %d of input %d", j, i)
-                               }
-                       case *mainchain.RawTxSigWitness:
-                               err := sw.Sign(tmpl, uint32(i), xprv)
-                               if err != nil {
-                                       return errors.WithDetailf(err, "adding signature(s) to raw-signature witness component %d of input %d", j, i)
-                               }
-                       }
-               }
-       }
-       return materializeWitnesses(tmpl)
-}
-
-func materializeWitnesses(txTemplate *mainchain.Template) error {
-       msg := txTemplate.Transaction
-
-       if msg == nil {
-               return errors.Wrap(txbuilder.ErrMissingRawTx)
-       }
-
-       if len(txTemplate.SigningInstructions) > len(msg.Inputs) {
-               return errors.Wrap(txbuilder.ErrBadInstructionCount)
-       }
-
-       for i, sigInst := range txTemplate.SigningInstructions {
-               if msg.Inputs[sigInst.Position] == nil {
-                       return errors.WithDetailf(txbuilder.ErrBadTxInputIdx, "signing instruction %d references missing tx input %d", i, sigInst.Position)
-               }
-
-               var witness [][]byte
-               for j, wc := range sigInst.WitnessComponents {
-                       err := wc.Materialize(&witness)
-                       if err != nil {
-                               return errors.WithDetailf(err, "error in witness component %d of input %d", j, i)
-                       }
-               }
-               msg.SetInputArguments(sigInst.Position, witness)
-       }
-
-       return nil
-}
index 4159472..5f6ca1b 100644 (file)
@@ -2,7 +2,6 @@ package mainchain
 
 import (
        "github.com/vapor/protocol/bc"
-       "github.com/vapor/protocol/bc/types/bytom"
        "github.com/vapor/protocol/vm"
        "github.com/vapor/protocol/vm/vmutil"
 )
@@ -34,7 +33,7 @@ func (o outputIDConstraint) code() []byte {
 // at the given index, optionally with the given refdatahash.
 type payConstraint struct {
        Index int
-       bytom.AssetAmount
+       bc.AssetAmount
        Program []byte
 }
 
index 727af33..ae631f9 100644 (file)
@@ -32,10 +32,6 @@ func (sw *RawTxSigWitness) Sign(tpl *Template, index uint32, xprv chainkd.XPrv)
                        // Already have a signature for this key
                        continue
                }
-               path := make([][]byte, len(keyID.DerivationPath))
-               for i, p := range keyID.DerivationPath {
-                       path[i] = p
-               }
                if keyID.XPub.String() != xprv.XPub().String() {
                        continue
                }
index 944b70c..ff81b67 100644 (file)
@@ -12,15 +12,11 @@ import (
 // AddWitnessKeys adds a SignatureWitness with the given quorum and
 // list of keys derived by applying the derivation path to each of the
 // xpubs.
-func (si *SigningInstruction) AddWitnessKeys(xpubs []chainkd.XPub, path [][]byte, quorum int) {
-       hexPath := make([]chainjson.HexBytes, 0, len(path))
-       for _, p := range path {
-               hexPath = append(hexPath, p)
-       }
+func (si *SigningInstruction) AddWitnessKeys(xpubs []chainkd.XPub, quorum int) {
 
        keyIDs := make([]keyID, 0, len(xpubs))
        for _, xpub := range xpubs {
-               keyIDs = append(keyIDs, keyID{xpub, hexPath})
+               keyIDs = append(keyIDs, keyID{XPub: xpub})
        }
 
        sw := &SignatureWitness{
@@ -51,6 +47,20 @@ func (si *SigningInstruction) AddRawWitnessKeys(xpubs []chainkd.XPub, path [][]b
        si.WitnessComponents = append(si.WitnessComponents, sw)
 }
 
+func (si *SigningInstruction) AddRawWitnessKeysWithoutPath(xpubs []chainkd.XPub, quorum int) {
+
+       keyIDs := make([]keyID, 0, len(xpubs))
+       for _, xpub := range xpubs {
+               keyIDs = append(keyIDs, keyID{XPub: xpub})
+       }
+
+       sw := &RawTxSigWitness{
+               Quorum: quorum,
+               Keys:   keyIDs,
+       }
+       si.WitnessComponents = append(si.WitnessComponents, sw)
+}
+
 // SigningInstruction gives directions for signing inputs in a TxTemplate.
 type SigningInstruction struct {
        Position          uint32             `json:"position"`
index 8c83f68..d0497a1 100644 (file)
@@ -6,7 +6,7 @@ import (
 
        "github.com/vapor/crypto/ed25519/chainkd"
        chainjson "github.com/vapor/encoding/json"
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
        bytomtypes "github.com/vapor/protocol/bc/types/bytom/types"
 )
 
@@ -24,7 +24,7 @@ type Template struct {
 }
 
 // Hash return sign hash
-func (t *Template) Hash(idx uint32) bytom.Hash {
+func (t *Template) Hash(idx uint32) bc.Hash {
        return t.Transaction.SigHash(idx)
 }
 
index 7cd2566..b462e4d 100644 (file)
@@ -51,7 +51,7 @@ xpub=$(cat key_pair | jq ".data.xpub" | sed "s/\"//g")
 
   ![pegin-address](pegin-address.png)
 
-- 在主链的dashboard,发送btm到mainchain_address
+- 在主链的dashboard,发送btm到mainchain_address 或者启动monitor_tx自动处理claim tx
 
 - 工具页面赎回交易填入参数,发送交易
 
diff --git a/equity/equity/LockWith2of3Keys b/equity/equity/LockWith2of3Keys
new file mode 100644 (file)
index 0000000..4a3da51
--- /dev/null
@@ -0,0 +1,7 @@
+contract LockWith3Keys(pubkey1, pubkey2, pubkey3: PublicKey) locks amount of asset {
+  clause unlockWith2Sigs(sig1, sig2: Signature) {
+    verify checkTxMultiSig([pubkey1, pubkey2, pubkey3], [sig1, sig2])
+    unlock amount of asset
+  }
+}
+
diff --git a/equity/pegin_contract/pegin_contract.go b/equity/pegin_contract/pegin_contract.go
new file mode 100644 (file)
index 0000000..55b27e5
--- /dev/null
@@ -0,0 +1,138 @@
+package pegin_contract
+
+import (
+       "crypto/hmac"
+       "crypto/sha256"
+       "errors"
+       "fmt"
+       "strings"
+
+       log "github.com/sirupsen/logrus"
+       "github.com/vapor/consensus"
+       "github.com/vapor/crypto/ed25519"
+       "github.com/vapor/crypto/ed25519/chainkd"
+       chainjson "github.com/vapor/encoding/json"
+       "github.com/vapor/equity/compiler"
+)
+
+const module = "pegin_contract"
+
+var lockWith2of3KeysFmt = `
+contract LockWith2of3Keys(%s) locks amount of asset {
+  clause unlockWith2Sigs(%s) {
+    verify checkTxMultiSig(%s)
+    unlock amount of asset
+  }
+}
+`
+
+func GetPeginContractPrograms(claimScript []byte) ([]byte, error) {
+
+       pubkeys := getNewXpub(consensus.ActiveNetParams.FedpegXPubs, claimScript)
+       num := len(pubkeys)
+       if num == 0 {
+               return nil, errors.New("Fedpeg's XPubs is empty")
+       }
+       params := ""
+       unlockParams := ""
+       checkParams := "["
+
+       for index := 0; index < num; index++ {
+               param := fmt.Sprintf("pubkey%d", index+1)
+               params += param
+               checkParams += param
+               if (index + 1) < num {
+                       params += ","
+                       checkParams += ","
+               }
+       }
+       params += ": PublicKey"
+       checkParams += "],["
+
+       signNum := getNumberOfSignaturesRequired(pubkeys)
+       for index := 0; index < signNum; index++ {
+               param := fmt.Sprintf("sig%d", index+1)
+               unlockParams += param
+               checkParams += param
+               if index+1 < signNum {
+                       unlockParams += ","
+                       checkParams += ","
+               }
+       }
+
+       unlockParams += ": Signature"
+       checkParams += "]"
+
+       lockWith2of3Keys := fmt.Sprintf(lockWith2of3KeysFmt, params, unlockParams, checkParams)
+       r := strings.NewReader(lockWith2of3Keys)
+       compiled, err := compiler.Compile(r)
+       if err != nil {
+               return nil, errors.New("Compile contract failed")
+       }
+
+       contract := compiled[len(compiled)-1]
+
+       if num < len(contract.Params) {
+               return nil, errors.New("Compile contract failed")
+       }
+
+       contractArgs, err := convertArguments(contract, pubkeys)
+       if err != nil {
+               log.WithFields(log.Fields{"module": module, "error": err}).Error("Convert arguments into contract parameters error")
+               return nil, errors.New("Convert arguments into contract parameters error")
+       }
+
+       instantProg, err := instantiateContract(contract, contractArgs)
+       if err != nil {
+               log.WithFields(log.Fields{"module": module, "error": err}).Error("Instantiate contract error")
+               return nil, errors.New("Instantiate contract error")
+       }
+
+       return instantProg, nil
+}
+
+func getNewXpub(federationRedeemXPub []chainkd.XPub, claimScript []byte) []ed25519.PublicKey {
+
+       var pubkeys []ed25519.PublicKey
+       for _, xpub := range federationRedeemXPub {
+               // pub + scriptPubKey 生成一个随机数A
+               var tmp [32]byte
+               h := hmac.New(sha256.New, xpub[:])
+               h.Write(claimScript)
+               tweak := h.Sum(tmp[:])
+               // pub +  A 生成一个新的公钥pub_new
+               chaildXPub := xpub.Child(tweak)
+               pubkeys = append(pubkeys, chaildXPub.PublicKey())
+       }
+       return pubkeys
+}
+
+func getNumberOfSignaturesRequired(pubkeys []ed25519.PublicKey) int {
+       return len(pubkeys)/2 + 1
+}
+
+// InstantiateContract instantiate contract parameters
+func instantiateContract(contract *compiler.Contract, args []compiler.ContractArg) ([]byte, error) {
+       program, err := compiler.Instantiate(contract.Body, contract.Params, contract.Recursive, args)
+       if err != nil {
+               return nil, err
+       }
+
+       return program, nil
+}
+
+func convertArguments(contract *compiler.Contract, args []ed25519.PublicKey) ([]compiler.ContractArg, error) {
+       var contractArgs []compiler.ContractArg
+       for i, p := range contract.Params {
+               var argument compiler.ContractArg
+               switch p.Type {
+               case "PublicKey":
+                       argument.S = (*chainjson.HexBytes)(&args[i])
+               default:
+                       return nil, errors.New("Contract parameter type error")
+               }
+               contractArgs = append(contractArgs, argument)
+       }
+
+       return contractArgs, nil
+}
index 61c51ae..45c335e 100644 (file)
@@ -205,27 +205,29 @@ func initActiveNetParams(config *cfg.Config) {
        if !exist {
                cmn.Exit(cmn.Fmt("chain_id[%v] don't exist", config.ChainID))
        }
-       var federationRedeemXPubs []chainkd.XPub
-       if fedpegXPubs := strings.Split(config.Side.FedpegXPubs, ","); len(fedpegXPubs) > 0 {
+       if config.Side.FedpegXPubs != "" {
+               var federationRedeemXPubs []chainkd.XPub
+               fedpegXPubs := strings.Split(config.Side.FedpegXPubs, ",")
                for _, xpubStr := range fedpegXPubs {
                        var xpub chainkd.XPub
                        xpub.UnmarshalText([]byte(xpubStr))
                        federationRedeemXPubs = append(federationRedeemXPubs, xpub)
                }
+               consensus.ActiveNetParams.FedpegXPubs = federationRedeemXPubs
        }
 
-       var signBlockXPubs []chainkd.XPub
-       if xPubs := strings.Split(config.Side.SignBlockXPubs, ","); len(xPubs) > 0 {
+       if config.Side.SignBlockXPubs != "" {
+               var signBlockXPubs []chainkd.XPub
+               xPubs := strings.Split(config.Side.SignBlockXPubs, ",")
                for _, xpubStr := range xPubs {
                        var xpub chainkd.XPub
                        xpub.UnmarshalText([]byte(xpubStr))
                        signBlockXPubs = append(signBlockXPubs, xpub)
                }
+               consensus.ActiveNetParams.SignBlockXPubs = signBlockXPubs
        }
 
        consensus.ActiveNetParams.Signer = config.Signer
-       consensus.ActiveNetParams.FedpegXPubs = federationRedeemXPubs
-       consensus.ActiveNetParams.SignBlockXPubs = signBlockXPubs
        consensus.ActiveNetParams.PeginMinDepth = config.Side.PeginMinDepth
        consensus.ActiveNetParams.ParentGenesisBlockHash = config.Side.ParentGenesisBlockHash
 }
@@ -326,7 +328,7 @@ func bytomdRPCCheck() bool {
        }
        if util.ValidatePegin {
                for {
-                       resp, err := util.CallRPC("/get-block-header", &Req{BlockHeight: 0})
+                       resp, err := util.CallRPC("/get-merkle-proof", &Req{BlockHeight: 0})
                        if err != nil {
                                log.Error("Call mainchain interface get-block-header failed")
                                time.Sleep(time.Millisecond * 1000)
index 3fdbcc0..149789f 100644 (file)
@@ -16,6 +16,7 @@ It has these top-level messages:
        ValueSource
        ValueDestination
        Proof
+       BytomBlockHeader
        BlockHeader
        TxHeader
        TxVerifyResult
@@ -290,6 +291,86 @@ func (m *Proof) GetControlProgram() []byte {
        return nil
 }
 
+type BytomBlockHeader struct {
+       Version               uint64             `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
+       Height                uint64             `protobuf:"varint,2,opt,name=height" json:"height,omitempty"`
+       PreviousBlockId       *Hash              `protobuf:"bytes,3,opt,name=previous_block_id,json=previousBlockId" json:"previous_block_id,omitempty"`
+       Timestamp             uint64             `protobuf:"varint,4,opt,name=timestamp" json:"timestamp,omitempty"`
+       TransactionsRoot      *Hash              `protobuf:"bytes,5,opt,name=transactions_root,json=transactionsRoot" json:"transactions_root,omitempty"`
+       TransactionStatusHash *Hash              `protobuf:"bytes,6,opt,name=transaction_status_hash,json=transactionStatusHash" json:"transaction_status_hash,omitempty"`
+       Nonce                 uint64             `protobuf:"varint,7,opt,name=nonce" json:"nonce,omitempty"`
+       Bits                  uint64             `protobuf:"varint,8,opt,name=bits" json:"bits,omitempty"`
+       TransactionStatus     *TransactionStatus `protobuf:"bytes,9,opt,name=transaction_status,json=transactionStatus" json:"transaction_status,omitempty"`
+}
+
+func (m *BytomBlockHeader) Reset()                    { *m = BytomBlockHeader{} }
+func (m *BytomBlockHeader) String() string            { return proto.CompactTextString(m) }
+func (*BytomBlockHeader) ProtoMessage()               {}
+func (*BytomBlockHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
+
+func (m *BytomBlockHeader) GetVersion() uint64 {
+       if m != nil {
+               return m.Version
+       }
+       return 0
+}
+
+func (m *BytomBlockHeader) GetHeight() uint64 {
+       if m != nil {
+               return m.Height
+       }
+       return 0
+}
+
+func (m *BytomBlockHeader) GetPreviousBlockId() *Hash {
+       if m != nil {
+               return m.PreviousBlockId
+       }
+       return nil
+}
+
+func (m *BytomBlockHeader) GetTimestamp() uint64 {
+       if m != nil {
+               return m.Timestamp
+       }
+       return 0
+}
+
+func (m *BytomBlockHeader) GetTransactionsRoot() *Hash {
+       if m != nil {
+               return m.TransactionsRoot
+       }
+       return nil
+}
+
+func (m *BytomBlockHeader) GetTransactionStatusHash() *Hash {
+       if m != nil {
+               return m.TransactionStatusHash
+       }
+       return nil
+}
+
+func (m *BytomBlockHeader) GetNonce() uint64 {
+       if m != nil {
+               return m.Nonce
+       }
+       return 0
+}
+
+func (m *BytomBlockHeader) GetBits() uint64 {
+       if m != nil {
+               return m.Bits
+       }
+       return 0
+}
+
+func (m *BytomBlockHeader) GetTransactionStatus() *TransactionStatus {
+       if m != nil {
+               return m.TransactionStatus
+       }
+       return nil
+}
+
 type BlockHeader struct {
        Version               uint64             `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
        Height                uint64             `protobuf:"varint,2,opt,name=height" json:"height,omitempty"`
@@ -306,7 +387,7 @@ type BlockHeader struct {
 func (m *BlockHeader) Reset()                    { *m = BlockHeader{} }
 func (m *BlockHeader) String() string            { return proto.CompactTextString(m) }
 func (*BlockHeader) ProtoMessage()               {}
-func (*BlockHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
+func (*BlockHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
 
 func (m *BlockHeader) GetVersion() uint64 {
        if m != nil {
@@ -388,7 +469,7 @@ type TxHeader struct {
 func (m *TxHeader) Reset()                    { *m = TxHeader{} }
 func (m *TxHeader) String() string            { return proto.CompactTextString(m) }
 func (*TxHeader) ProtoMessage()               {}
-func (*TxHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
+func (*TxHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
 
 func (m *TxHeader) GetVersion() uint64 {
        if m != nil {
@@ -425,7 +506,7 @@ type TxVerifyResult struct {
 func (m *TxVerifyResult) Reset()                    { *m = TxVerifyResult{} }
 func (m *TxVerifyResult) String() string            { return proto.CompactTextString(m) }
 func (*TxVerifyResult) ProtoMessage()               {}
-func (*TxVerifyResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
+func (*TxVerifyResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
 
 func (m *TxVerifyResult) GetStatusFail() bool {
        if m != nil {
@@ -442,7 +523,7 @@ type TransactionStatus struct {
 func (m *TransactionStatus) Reset()                    { *m = TransactionStatus{} }
 func (m *TransactionStatus) String() string            { return proto.CompactTextString(m) }
 func (*TransactionStatus) ProtoMessage()               {}
-func (*TransactionStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
+func (*TransactionStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
 
 func (m *TransactionStatus) GetVersion() uint64 {
        if m != nil {
@@ -468,7 +549,7 @@ type Mux struct {
 func (m *Mux) Reset()                    { *m = Mux{} }
 func (m *Mux) String() string            { return proto.CompactTextString(m) }
 func (*Mux) ProtoMessage()               {}
-func (*Mux) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
+func (*Mux) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
 
 func (m *Mux) GetSources() []*ValueSource {
        if m != nil {
@@ -506,7 +587,7 @@ type Coinbase struct {
 func (m *Coinbase) Reset()                    { *m = Coinbase{} }
 func (m *Coinbase) String() string            { return proto.CompactTextString(m) }
 func (*Coinbase) ProtoMessage()               {}
-func (*Coinbase) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
+func (*Coinbase) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
 
 func (m *Coinbase) GetWitnessDestination() *ValueDestination {
        if m != nil {
@@ -531,7 +612,7 @@ type Output struct {
 func (m *Output) Reset()                    { *m = Output{} }
 func (m *Output) String() string            { return proto.CompactTextString(m) }
 func (*Output) ProtoMessage()               {}
-func (*Output) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
+func (*Output) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
 
 func (m *Output) GetSource() *ValueSource {
        if m != nil {
@@ -562,7 +643,7 @@ type Retirement struct {
 func (m *Retirement) Reset()                    { *m = Retirement{} }
 func (m *Retirement) String() string            { return proto.CompactTextString(m) }
 func (*Retirement) ProtoMessage()               {}
-func (*Retirement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
+func (*Retirement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
 
 func (m *Retirement) GetSource() *ValueSource {
        if m != nil {
@@ -590,7 +671,7 @@ type Issuance struct {
 func (m *Issuance) Reset()                    { *m = Issuance{} }
 func (m *Issuance) String() string            { return proto.CompactTextString(m) }
 func (*Issuance) ProtoMessage()               {}
-func (*Issuance) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
+func (*Issuance) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
 
 func (m *Issuance) GetNonceHash() *Hash {
        if m != nil {
@@ -644,7 +725,7 @@ type Spend struct {
 func (m *Spend) Reset()                    { *m = Spend{} }
 func (m *Spend) String() string            { return proto.CompactTextString(m) }
 func (*Spend) ProtoMessage()               {}
-func (*Spend) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
+func (*Spend) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
 
 func (m *Spend) GetSpentOutputId() *Hash {
        if m != nil {
@@ -685,7 +766,7 @@ type Claim struct {
 func (m *Claim) Reset()                    { *m = Claim{} }
 func (m *Claim) String() string            { return proto.CompactTextString(m) }
 func (*Claim) ProtoMessage()               {}
-func (*Claim) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
+func (*Claim) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
 
 func (m *Claim) GetSpentOutputId() *Hash {
        if m != nil {
@@ -731,6 +812,7 @@ func init() {
        proto.RegisterType((*ValueSource)(nil), "bc.ValueSource")
        proto.RegisterType((*ValueDestination)(nil), "bc.ValueDestination")
        proto.RegisterType((*Proof)(nil), "bc.Proof")
+       proto.RegisterType((*BytomBlockHeader)(nil), "bc.BytomBlockHeader")
        proto.RegisterType((*BlockHeader)(nil), "bc.BlockHeader")
        proto.RegisterType((*TxHeader)(nil), "bc.TxHeader")
        proto.RegisterType((*TxVerifyResult)(nil), "bc.TxVerifyResult")
@@ -747,67 +829,68 @@ func init() {
 func init() { proto.RegisterFile("bc.proto", fileDescriptor0) }
 
 var fileDescriptor0 = []byte{
-       // 982 bytes of a gzipped FileDescriptorProto
-       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xcd, 0x6e, 0xdb, 0xc6,
-       0x13, 0x87, 0x24, 0xea, 0x6b, 0xe4, 0x58, 0xd6, 0xda, 0xc9, 0x9f, 0x08, 0xf2, 0x47, 0x02, 0x02,
-       0x89, 0x5b, 0x14, 0x30, 0x6c, 0x39, 0x6d, 0x2f, 0x3d, 0xd4, 0xb5, 0x9b, 0x46, 0x07, 0x23, 0xc6,
-       0xda, 0xf0, 0x95, 0x58, 0x91, 0x2b, 0x69, 0x51, 0x8a, 0xab, 0xee, 0x2e, 0x55, 0xc7, 0xb7, 0x3e,
-       0x44, 0x8f, 0x7d, 0x8e, 0x3e, 0x42, 0x4f, 0x7d, 0x92, 0xbe, 0x44, 0xb1, 0xc3, 0xa5, 0x44, 0x7d,
-       0xe4, 0x0b, 0x45, 0x0f, 0xbd, 0x71, 0x66, 0x67, 0xe7, 0xe3, 0x37, 0xbf, 0x99, 0x25, 0xb4, 0x86,
-       0xd1, 0xd1, 0x4c, 0x49, 0x23, 0x49, 0x75, 0x18, 0x05, 0xaf, 0xc0, 0x7b, 0xcd, 0xf4, 0x84, 0xec,
-       0x42, 0x75, 0x7e, 0xec, 0x57, 0x9e, 0x55, 0x3e, 0x6b, 0xd0, 0xea, 0xfc, 0x18, 0xe5, 0x13, 0xbf,
-       0xea, 0xe4, 0x13, 0x94, 0xfb, 0x7e, 0xcd, 0xc9, 0x7d, 0x94, 0x4f, 0x7d, 0xcf, 0xc9, 0xa7, 0xc1,
-       0x37, 0xd0, 0xbc, 0x52, 0x72, 0xac, 0xd8, 0x94, 0xfc, 0x1f, 0x60, 0x3e, 0x0d, 0xe7, 0x5c, 0x69,
-       0x21, 0x53, 0x74, 0xe9, 0xd1, 0xf6, 0x7c, 0x7a, 0x9b, 0x2b, 0x08, 0x01, 0x2f, 0x92, 0x31, 0x47,
-       0xdf, 0x3b, 0x14, 0xbf, 0x83, 0x01, 0x34, 0xcf, 0xb4, 0xe6, 0x66, 0x70, 0xf1, 0x8f, 0x13, 0xb9,
-       0x84, 0x0e, 0xba, 0x3a, 0x9b, 0xca, 0x2c, 0x35, 0xe4, 0x05, 0xb4, 0x98, 0x15, 0x43, 0x11, 0xa3,
-       0xd3, 0x4e, 0xbf, 0x73, 0x34, 0x8c, 0x8e, 0x5c, 0x34, 0xda, 0xc4, 0xc3, 0x41, 0x4c, 0x1e, 0x41,
-       0x83, 0xe1, 0x0d, 0x0c, 0xe5, 0x51, 0x27, 0x05, 0x63, 0xe8, 0xa2, 0xed, 0x05, 0x1f, 0x89, 0x54,
-       0x18, 0x5b, 0xc0, 0x57, 0xb0, 0x27, 0xb4, 0xce, 0x58, 0x1a, 0xf1, 0x70, 0x96, 0xd7, 0x5c, 0x76,
-       0xed, 0x60, 0xa0, 0xdd, 0xc2, 0xa8, 0xc0, 0xe5, 0x09, 0x78, 0x31, 0x33, 0x0c, 0x03, 0x74, 0xfa,
-       0x2d, 0x6b, 0x6b, 0xa1, 0xa7, 0xa8, 0x0d, 0x12, 0xe8, 0xdc, 0xb2, 0x24, 0xe3, 0xd7, 0x32, 0x53,
-       0x11, 0x27, 0x8f, 0xa1, 0xa6, 0xf8, 0xc8, 0xf9, 0x5d, 0xda, 0x5a, 0x25, 0x79, 0x0e, 0xf5, 0xb9,
-       0x35, 0x75, 0x9e, 0xba, 0x8b, 0x82, 0xf2, 0x9a, 0x69, 0x7e, 0x4a, 0x1e, 0x43, 0x6b, 0x26, 0x35,
-       0xe6, 0x8c, 0x78, 0x79, 0x74, 0x21, 0x07, 0x3f, 0xc1, 0x1e, 0x46, 0xbb, 0xe0, 0xda, 0x88, 0x94,
-       0x61, 0x5d, 0xff, 0x72, 0xc8, 0x73, 0xa8, 0x5f, 0x29, 0x29, 0x47, 0x96, 0x00, 0x5a, 0x8c, 0x73,
-       0x66, 0xec, 0x50, 0xfc, 0x26, 0x2f, 0x60, 0x37, 0x92, 0xa9, 0x51, 0x32, 0x71, 0x68, 0x39, 0x7a,
-       0xac, 0x69, 0x83, 0xdf, 0x6a, 0xd0, 0xf9, 0x2e, 0x91, 0xd1, 0x8f, 0xaf, 0x39, 0x8b, 0xb9, 0x22,
-       0x3e, 0x34, 0x57, 0x89, 0x56, 0x88, 0xb6, 0xa1, 0x13, 0x2e, 0xc6, 0x93, 0x45, 0x43, 0x73, 0x89,
-       0xbc, 0x84, 0xde, 0x4c, 0xf1, 0xb9, 0x90, 0x99, 0x0e, 0x87, 0xd6, 0x93, 0x65, 0x46, 0x6d, 0xad,
-       0xe6, 0x6e, 0x61, 0x82, 0xb1, 0x06, 0x31, 0x79, 0x02, 0x6d, 0x23, 0xa6, 0x5c, 0x1b, 0x36, 0x9d,
-       0x21, 0xd9, 0x3c, 0xba, 0x54, 0x90, 0x2f, 0xa1, 0x67, 0x14, 0x4b, 0x35, 0x8b, 0x6c, 0xa5, 0x3a,
-       0x54, 0x52, 0x1a, 0xbf, 0xbe, 0xe6, 0x73, 0xaf, 0x6c, 0x42, 0xa5, 0x34, 0xe4, 0x5b, 0xf8, 0x5f,
-       0x49, 0x17, 0x6a, 0xc3, 0x4c, 0xa6, 0xc3, 0x09, 0xd3, 0x13, 0xbf, 0xb1, 0x76, 0xf9, 0x61, 0xc9,
-       0xf0, 0x1a, 0xed, 0x70, 0x6a, 0x0f, 0xa0, 0x9e, 0xca, 0x34, 0xe2, 0x7e, 0x13, 0x53, 0xca, 0x05,
-       0x0b, 0xf0, 0x50, 0x18, 0xed, 0xb7, 0x50, 0x89, 0xdf, 0xe4, 0x02, 0xc8, 0x66, 0x2c, 0xbf, 0x8d,
-       0x61, 0x1e, 0xda, 0x30, 0x37, 0xeb, 0x01, 0x68, 0x6f, 0x23, 0x26, 0x79, 0xea, 0x7a, 0xe8, 0x03,
-       0x5e, 0x6c, 0x3b, 0xbe, 0xcb, 0x11, 0xcd, 0xf5, 0xc1, 0xaf, 0x15, 0x68, 0xdd, 0xdc, 0x7d, 0xb0,
-       0x39, 0x87, 0xd0, 0xd5, 0x5c, 0x09, 0x96, 0x88, 0x7b, 0x1e, 0x87, 0x5a, 0xdc, 0x73, 0xd7, 0xa5,
-       0xdd, 0xa5, 0xfa, 0x5a, 0xdc, 0x73, 0xbb, 0x4b, 0x2c, 0xcc, 0xa1, 0x62, 0xe9, 0x98, 0x3b, 0x4a,
-       0x21, 0xf0, 0xd4, 0x2a, 0xc8, 0x21, 0x80, 0xe2, 0x3a, 0x4b, 0xec, 0x78, 0x6b, 0xdf, 0x7b, 0x56,
-       0x5b, 0x01, 0xad, 0x9d, 0x9f, 0x0d, 0x62, 0x1d, 0x9c, 0xc0, 0xee, 0xcd, 0xdd, 0x2d, 0x57, 0x62,
-       0xf4, 0x96, 0xa2, 0x92, 0x3c, 0x85, 0x8e, 0x03, 0x7c, 0xc4, 0x44, 0x82, 0x09, 0xb6, 0x28, 0xe4,
-       0xaa, 0x57, 0x4c, 0x24, 0xc1, 0x08, 0x7a, 0x1b, 0x98, 0xbc, 0xa7, 0xa4, 0xaf, 0xe1, 0xc1, 0x1c,
-       0xfd, 0x17, 0xd8, 0x56, 0x31, 0x1b, 0x82, 0xd8, 0xae, 0x84, 0xa6, 0x3b, 0xb9, 0x61, 0xee, 0x32,
-       0xf8, 0xb3, 0x02, 0xb5, 0xcb, 0xec, 0x8e, 0x7c, 0x0e, 0x4d, 0x8d, 0xb3, 0xaf, 0xfd, 0x0a, 0x5e,
-       0xc5, 0x21, 0x2b, 0xed, 0x04, 0x5a, 0x9c, 0x93, 0xe7, 0xd0, 0x9c, 0x95, 0xc6, 0x64, 0x6d, 0xf1,
-       0x14, 0x67, 0xe4, 0x07, 0x38, 0xf8, 0x59, 0x98, 0x94, 0x6b, 0x1d, 0xc6, 0xcb, 0x39, 0xd7, 0x7e,
-       0x0d, 0xdd, 0x1f, 0x2c, 0xdc, 0x97, 0x96, 0x00, 0xdd, 0x77, 0x37, 0x4a, 0x3a, 0x4d, 0xbe, 0x80,
-       0x5e, 0xe1, 0x88, 0xa9, 0x71, 0x36, 0xe5, 0xa9, 0xc9, 0xd1, 0xde, 0xa1, 0x7b, 0xee, 0xe0, 0xac,
-       0xd0, 0x07, 0x12, 0x5a, 0xe7, 0x52, 0xa4, 0x43, 0xa6, 0x39, 0xf9, 0x1e, 0xf6, 0xb7, 0x64, 0xe0,
-       0x56, 0xcc, 0xf6, 0x04, 0xc8, 0x66, 0x02, 0x76, 0xfa, 0x98, 0x1a, 0x0a, 0xa3, 0x98, 0x7a, 0xeb,
-       0x16, 0xc3, 0x52, 0x11, 0xfc, 0x52, 0x81, 0xc6, 0x9b, 0xcc, 0xcc, 0x32, 0x43, 0x0e, 0xa1, 0x91,
-       0x63, 0xe4, 0x42, 0x6c, 0x40, 0xe8, 0x8e, 0xc9, 0x4b, 0xe8, 0xba, 0xcd, 0x12, 0xbe, 0x07, 0xc9,
-       0xb5, 0xed, 0x63, 0xbb, 0x2f, 0x55, 0x2c, 0x52, 0x96, 0x38, 0x2a, 0x16, 0x62, 0xf0, 0x06, 0x80,
-       0x72, 0x23, 0x14, 0xb7, 0x18, 0x7c, 0x7c, 0x1a, 0x25, 0x87, 0xd5, 0x55, 0x87, 0xbf, 0x57, 0xa1,
-       0x35, 0x70, 0x0f, 0x88, 0xa5, 0x39, 0x4e, 0x76, 0xbe, 0x1b, 0xd6, 0x17, 0x74, 0x1b, 0xcf, 0x70,
-       0x1f, 0x7c, 0xe4, 0x9a, 0x7e, 0x47, 0x5b, 0x6a, 0x9f, 0xd8, 0x96, 0x4b, 0xf0, 0x17, 0xb4, 0xc0,
-       0x37, 0x36, 0x5e, 0x3c, 0x92, 0xb8, 0x23, 0x3b, 0xfd, 0xfd, 0x45, 0x02, 0xcb, 0xf7, 0x93, 0x3e,
-       0x2a, 0x28, 0xb3, 0xf6, 0xae, 0x6e, 0x65, 0x59, 0x7d, 0x3b, 0xcb, 0xca, 0xc8, 0x35, 0x56, 0x91,
-       0xfb, 0xa3, 0x02, 0xf5, 0xeb, 0x19, 0x4f, 0x63, 0x72, 0x0c, 0x5d, 0x3d, 0xe3, 0xa9, 0x09, 0x25,
-       0xb2, 0x63, 0xf9, 0x0b, 0xb0, 0xc4, 0xee, 0x01, 0x1a, 0xe4, 0xec, 0x19, 0xc4, 0xef, 0x02, 0xa6,
-       0xfa, 0x89, 0xc0, 0x6c, 0xad, 0xa4, 0xf6, 0xe1, 0x4a, 0xbc, 0xd5, 0x4a, 0xfe, 0xaa, 0x40, 0xfd,
-       0x3c, 0x61, 0x62, 0xfa, 0x5f, 0xaf, 0x84, 0x04, 0xb0, 0x73, 0xc5, 0xc7, 0x22, 0x75, 0x57, 0x5c,
-       0x57, 0x57, 0x74, 0xc3, 0x06, 0xfe, 0x94, 0x9e, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x29,
-       0x9e, 0x4e, 0xa0, 0x0a, 0x00, 0x00,
+       // 999 bytes of a gzipped FileDescriptorProto
+       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x57, 0xcb, 0x6e, 0x1b, 0x37,
+       0x14, 0x85, 0x34, 0xa3, 0xd7, 0x95, 0x63, 0xd9, 0xb4, 0x93, 0x0e, 0x82, 0x14, 0x09, 0x06, 0x48,
+       0xdc, 0xa2, 0x80, 0xe1, 0x47, 0xda, 0x6e, 0xba, 0xa8, 0x63, 0x37, 0x8d, 0x16, 0x46, 0x0c, 0xda,
+       0xf0, 0x76, 0x40, 0xcd, 0x50, 0x32, 0xd1, 0xd1, 0x50, 0x25, 0x39, 0xaa, 0xed, 0x5d, 0x3e, 0xa2,
+       0xcb, 0x7e, 0x47, 0x3f, 0xa1, 0xab, 0x7e, 0x49, 0x7f, 0xa2, 0xe0, 0x1d, 0x8e, 0x34, 0x92, 0x95,
+       0x17, 0x8a, 0xa2, 0x28, 0x90, 0x9d, 0xee, 0xe1, 0xe5, 0x7d, 0x1c, 0x5e, 0x9e, 0xa1, 0xa0, 0x3d,
+       0x88, 0x77, 0x27, 0x4a, 0x1a, 0x49, 0xea, 0x83, 0x38, 0x7c, 0x09, 0xfe, 0x2b, 0xa6, 0xaf, 0xc8,
+       0x3a, 0xd4, 0xa7, 0x7b, 0x41, 0xed, 0x49, 0xed, 0x8b, 0x26, 0xad, 0x4f, 0xf7, 0xd0, 0xde, 0x0f,
+       0xea, 0xce, 0xde, 0x47, 0xfb, 0x20, 0xf0, 0x9c, 0x7d, 0x80, 0xf6, 0x61, 0xe0, 0x3b, 0xfb, 0x30,
+       0xfc, 0x0e, 0x5a, 0x67, 0x4a, 0x8e, 0x14, 0x1b, 0x93, 0xcf, 0x01, 0xa6, 0xe3, 0x68, 0xca, 0x95,
+       0x16, 0x32, 0xc3, 0x90, 0x3e, 0xed, 0x4c, 0xc7, 0x97, 0x05, 0x40, 0x08, 0xf8, 0xb1, 0x4c, 0x38,
+       0xc6, 0x5e, 0xa3, 0xf8, 0x3b, 0xec, 0x43, 0xeb, 0x48, 0x6b, 0x6e, 0xfa, 0x27, 0xff, 0xb8, 0x90,
+       0x53, 0xe8, 0x62, 0xa8, 0xa3, 0xb1, 0xcc, 0x33, 0x43, 0x9e, 0x41, 0x9b, 0x59, 0x33, 0x12, 0x09,
+       0x06, 0xed, 0x1e, 0x74, 0x77, 0x07, 0xf1, 0xae, 0xcb, 0x46, 0x5b, 0xb8, 0xd8, 0x4f, 0xc8, 0x03,
+       0x68, 0x32, 0xdc, 0x81, 0xa9, 0x7c, 0xea, 0xac, 0x70, 0x04, 0x3d, 0xf4, 0x3d, 0xe1, 0x43, 0x91,
+       0x09, 0x63, 0x1b, 0xf8, 0x06, 0x36, 0x84, 0xd6, 0x39, 0xcb, 0x62, 0x1e, 0x4d, 0x8a, 0x9e, 0xab,
+       0xa1, 0x1d, 0x0d, 0xb4, 0x57, 0x3a, 0x95, 0xbc, 0x3c, 0x02, 0x3f, 0x61, 0x86, 0x61, 0x82, 0xee,
+       0x41, 0xdb, 0xfa, 0x5a, 0xea, 0x29, 0xa2, 0x61, 0x0a, 0xdd, 0x4b, 0x96, 0xe6, 0xfc, 0x5c, 0xe6,
+       0x2a, 0xe6, 0xe4, 0x21, 0x78, 0x8a, 0x0f, 0x5d, 0xdc, 0xb9, 0xaf, 0x05, 0xc9, 0x53, 0x68, 0x4c,
+       0xad, 0xab, 0x8b, 0xd4, 0x9b, 0x35, 0x54, 0xf4, 0x4c, 0x8b, 0x55, 0xf2, 0x10, 0xda, 0x13, 0xa9,
+       0xb1, 0x66, 0xe4, 0xcb, 0xa7, 0x33, 0x3b, 0xfc, 0x19, 0x36, 0x30, 0xdb, 0x09, 0xd7, 0x46, 0x64,
+       0x0c, 0xfb, 0xfa, 0x97, 0x53, 0x1e, 0x43, 0xe3, 0x4c, 0x49, 0x39, 0xb4, 0x03, 0xa0, 0xc5, 0xa8,
+       0x98, 0x8c, 0x35, 0x8a, 0xbf, 0xc9, 0x33, 0x58, 0x8f, 0x65, 0x66, 0x94, 0x4c, 0x1d, 0x5b, 0x6e,
+       0x3c, 0x96, 0xd0, 0xf0, 0x8d, 0x07, 0x1b, 0x2f, 0x6e, 0x8c, 0x1c, 0xbf, 0x48, 0x65, 0xfc, 0xd3,
+       0x2b, 0xce, 0x12, 0xae, 0x48, 0x00, 0xad, 0xc5, 0x69, 0x2b, 0x4d, 0x7b, 0xaa, 0x57, 0x5c, 0x8c,
+       0xae, 0x66, 0xa7, 0x5a, 0x58, 0xe4, 0x39, 0x6c, 0x4e, 0x14, 0x9f, 0x0a, 0x99, 0xeb, 0x68, 0x60,
+       0x23, 0xd9, 0xf1, 0xf0, 0x96, 0x1a, 0xef, 0x95, 0x2e, 0x98, 0xab, 0x9f, 0x90, 0x47, 0xd0, 0x31,
+       0x62, 0xcc, 0xb5, 0x61, 0xe3, 0x09, 0x4e, 0x9c, 0x4f, 0xe7, 0x00, 0xf9, 0x1a, 0x36, 0x8d, 0x62,
+       0x99, 0x66, 0xb1, 0x6d, 0x57, 0x47, 0x4a, 0x4a, 0x13, 0x34, 0x96, 0x62, 0x6e, 0x54, 0x5d, 0xa8,
+       0x94, 0x86, 0x7c, 0x0f, 0x9f, 0x55, 0xb0, 0x48, 0x1b, 0x66, 0x72, 0x1d, 0x5d, 0x31, 0x7d, 0x15,
+       0x34, 0x97, 0x36, 0xdf, 0xaf, 0x38, 0x9e, 0xa3, 0x1f, 0x5e, 0xdd, 0x6d, 0x68, 0x64, 0x32, 0x8b,
+       0x79, 0xd0, 0xc2, 0x92, 0x0a, 0xc3, 0xb2, 0x3c, 0x10, 0x46, 0x07, 0x6d, 0x04, 0xf1, 0x37, 0x39,
+       0x01, 0x72, 0x37, 0x57, 0xd0, 0xc1, 0x34, 0xf7, 0x6d, 0x9a, 0x8b, 0xe5, 0x04, 0x74, 0xf3, 0x4e,
+       0xce, 0xf0, 0x37, 0x0f, 0xba, 0x9f, 0xe8, 0xff, 0xaf, 0xe8, 0x27, 0x8f, 0xdd, 0x3d, 0x0a, 0x00,
+       0x37, 0x76, 0x9c, 0xe6, 0xc8, 0x21, 0x2d, 0xf0, 0xf0, 0xd7, 0x1a, 0xb4, 0x2f, 0xae, 0xdf, 0x7b,
+       0x38, 0x3b, 0xd0, 0xd3, 0x5c, 0x09, 0x96, 0x8a, 0x5b, 0x9e, 0x44, 0x5a, 0xdc, 0x72, 0x77, 0x4a,
+       0xeb, 0x73, 0xf8, 0x5c, 0xdc, 0x72, 0xab, 0xe7, 0x96, 0xe6, 0x48, 0xb1, 0x6c, 0xc4, 0xdd, 0xb5,
+       0x46, 0xe2, 0xa9, 0x05, 0xc8, 0x0e, 0x80, 0xe2, 0x3a, 0x4f, 0xad, 0xc4, 0xea, 0xc0, 0x7f, 0xe2,
+       0x2d, 0x90, 0xd6, 0x29, 0xd6, 0xfa, 0x89, 0x0e, 0xf7, 0x61, 0xfd, 0xe2, 0xfa, 0x92, 0x2b, 0x31,
+       0xbc, 0xa1, 0x08, 0x92, 0xc7, 0xd0, 0x75, 0x84, 0x0f, 0x99, 0x48, 0xb1, 0xc0, 0x36, 0x85, 0x02,
+       0x7a, 0xc9, 0x44, 0x1a, 0x0e, 0x61, 0xf3, 0x0e, 0x27, 0xef, 0x68, 0xe9, 0x5b, 0xb8, 0x37, 0xc5,
+       0xf8, 0x25, 0xb7, 0x75, 0xac, 0x86, 0x20, 0xb7, 0x0b, 0xa9, 0xe9, 0x5a, 0xe1, 0xe8, 0x46, 0xfa,
+       0xcf, 0x1a, 0x78, 0xa7, 0xf9, 0x35, 0xf9, 0x12, 0x5a, 0x1a, 0xf5, 0x57, 0x07, 0x35, 0xdc, 0x8a,
+       0x42, 0x57, 0xd1, 0x65, 0x5a, 0xae, 0x93, 0xa7, 0xd0, 0x9a, 0x54, 0xa4, 0x6a, 0x49, 0xfc, 0xcb,
+       0x35, 0xf2, 0x23, 0x6c, 0xff, 0x22, 0x4c, 0xc6, 0xb5, 0x8e, 0x92, 0xb9, 0xd6, 0xea, 0xc0, 0xc3,
+       0xf0, 0xdb, 0xb3, 0xf0, 0x15, 0x21, 0xa6, 0x5b, 0x6e, 0x47, 0x05, 0xd3, 0xe4, 0x2b, 0xd8, 0x2c,
+       0x03, 0x31, 0x35, 0xca, 0xc7, 0x3c, 0x33, 0x05, 0xdb, 0x6b, 0x74, 0xc3, 0x2d, 0x1c, 0x95, 0x78,
+       0x28, 0xa1, 0x7d, 0x2c, 0x45, 0x36, 0x60, 0x9a, 0x93, 0x1f, 0x60, 0x6b, 0x45, 0x05, 0x4e, 0xe6,
+       0x57, 0x17, 0x40, 0xee, 0x16, 0x60, 0x6f, 0x1f, 0x53, 0x03, 0x61, 0x14, 0x53, 0x37, 0x4e, 0x9c,
+       0xe7, 0x40, 0xf8, 0xa6, 0x06, 0xcd, 0xd7, 0xb9, 0x99, 0xe4, 0x86, 0xec, 0x40, 0xb3, 0xe0, 0xc8,
+       0xa5, 0xb8, 0x43, 0xa1, 0x5b, 0x26, 0xcf, 0xa1, 0xe7, 0xd4, 0x3d, 0x7a, 0x07, 0x93, 0x4b, 0x5f,
+       0x00, 0x7b, 0xfa, 0x52, 0x25, 0x22, 0x63, 0xa9, 0x1b, 0xc5, 0xd2, 0x0c, 0x5f, 0x03, 0x50, 0x6e,
+       0x84, 0xe2, 0x96, 0x83, 0x0f, 0x2f, 0xa3, 0x12, 0xb0, 0xbe, 0x18, 0xf0, 0xf7, 0x3a, 0xb4, 0xfb,
+       0xee, 0x23, 0x6e, 0xc7, 0x1c, 0x6f, 0x76, 0xa1, 0x0d, 0xcb, 0x1f, 0xc9, 0x0e, 0xae, 0xa1, 0x1e,
+       0x7c, 0xe0, 0xa7, 0xf2, 0x2d, 0xc7, 0xe2, 0x7d, 0xe4, 0xb1, 0x9c, 0x42, 0x30, 0x1b, 0x0b, 0x7c,
+       0xe7, 0x24, 0xb3, 0x87, 0x0a, 0x6a, 0x64, 0xf7, 0x60, 0x6b, 0x56, 0xc0, 0xfc, 0x0d, 0x43, 0x1f,
+       0x94, 0x23, 0xb3, 0xf4, 0xb6, 0x59, 0x39, 0x65, 0x8d, 0xd5, 0x53, 0x56, 0x65, 0xae, 0xb9, 0xc8,
+       0xdc, 0x1f, 0x35, 0x68, 0x9c, 0x4f, 0x78, 0x96, 0x90, 0x3d, 0xe8, 0xe9, 0x09, 0xcf, 0x4c, 0x24,
+       0x71, 0x3a, 0xe6, 0xcf, 0xb0, 0x39, 0x77, 0xf7, 0xd0, 0xa1, 0x98, 0x9e, 0x7e, 0xf2, 0x36, 0x62,
+       0xea, 0x1f, 0x49, 0xcc, 0xca, 0x4e, 0xbc, 0xf7, 0x77, 0xe2, 0x2f, 0x76, 0xf2, 0x57, 0x0d, 0x1a,
+       0xc7, 0x29, 0x13, 0xe3, 0xff, 0x7b, 0x27, 0x24, 0x84, 0xb5, 0x33, 0x3e, 0x12, 0x99, 0xdb, 0xe2,
+       0x4e, 0x75, 0x01, 0x1b, 0x34, 0xf1, 0x8f, 0xc1, 0xe1, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9d,
+       0xe4, 0x01, 0xce, 0x24, 0x0c, 0x00, 0x00,
 }
index d333667..b12c67d 100644 (file)
@@ -53,6 +53,18 @@ message Proof {
        bytes controlProgram = 2;
 }
 
+message BytomBlockHeader {
+  uint64            version                 = 1;
+  uint64            height                  = 2;
+  Hash              previous_block_id       = 3;
+  uint64            timestamp               = 4;
+  Hash              transactions_root       = 5;
+  Hash              transaction_status_hash = 6;
+  uint64            nonce                   = 7;
+  uint64            bits                    = 8;
+  TransactionStatus transaction_status      = 9;
+}
+
 message BlockHeader {
   uint64            version                 = 1;
   uint64            height                  = 2;
similarity index 57%
rename from protocol/bc/types/bytom/blockheader.go
rename to protocol/bc/bytom_blockheader.go
index 126481d..6259a98 100644 (file)
@@ -1,12 +1,9 @@
-package bytom
+package bc
 
 import "io"
 
-// BlockHeader contains the header information for a blockchain
-// block. It satisfies the Entry interface.
-
-func (BlockHeader) typ() string { return "blockheader" }
-func (bh *BlockHeader) writeForHash(w io.Writer) {
+func (BytomBlockHeader) typ() string { return "blockheader" }
+func (bh *BytomBlockHeader) writeForHash(w io.Writer) {
        mustWriteForHash(w, bh.Version)
        mustWriteForHash(w, bh.Height)
        mustWriteForHash(w, bh.PreviousBlockId)
@@ -17,10 +14,10 @@ func (bh *BlockHeader) writeForHash(w io.Writer) {
        mustWriteForHash(w, bh.Nonce)
 }
 
-// NewBlockHeader creates a new BlockHeader and populates
+// NewBytomBlockHeader creates a new BlockHeader and populates
 // its body.
-func NewBlockHeader(version, height uint64, previousBlockID *Hash, timestamp uint64, transactionsRoot, transactionStatusHash *Hash, nonce, bits uint64) *BlockHeader {
-       return &BlockHeader{
+func NewBytomBlockHeader(version, height uint64, previousBlockID *Hash, timestamp uint64, transactionsRoot, transactionStatusHash *Hash, nonce, bits uint64) *BytomBlockHeader {
+       return &BytomBlockHeader{
                Version:               version,
                Height:                height,
                PreviousBlockId:       previousBlockID,
diff --git a/protocol/bc/types/bytom/asset.go b/protocol/bc/types/bytom/asset.go
deleted file mode 100644 (file)
index fecdf1e..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-package bytom
-
-import (
-       "encoding/binary"
-       "errors"
-       "io"
-
-       "github.com/vapor/crypto/sha3pool"
-       "github.com/vapor/encoding/blockchain"
-)
-
-// NewAssetID convert byte array to aseet id
-func NewAssetID(b [32]byte) (a AssetID) {
-       return AssetID{
-               V0: binary.BigEndian.Uint64(b[0:8]),
-               V1: binary.BigEndian.Uint64(b[8:16]),
-               V2: binary.BigEndian.Uint64(b[16:24]),
-               V3: binary.BigEndian.Uint64(b[24:32]),
-       }
-}
-
-// Byte32 return the byte array representation
-func (a AssetID) Byte32() (b32 [32]byte) { return Hash(a).Byte32() }
-
-// MarshalText satisfies the TextMarshaler interface.
-func (a AssetID) MarshalText() ([]byte, error) { return Hash(a).MarshalText() }
-
-// UnmarshalText satisfies the TextUnmarshaler interface.
-func (a *AssetID) UnmarshalText(b []byte) error { return (*Hash)(a).UnmarshalText(b) }
-
-// UnmarshalJSON satisfies the json.Unmarshaler interface.
-func (a *AssetID) UnmarshalJSON(b []byte) error { return (*Hash)(a).UnmarshalJSON(b) }
-
-// Bytes returns the byte representation.
-func (a AssetID) Bytes() []byte { return Hash(a).Bytes() }
-
-// WriteTo satisfies the io.WriterTo interface.
-func (a AssetID) WriteTo(w io.Writer) (int64, error) { return Hash(a).WriteTo(w) }
-
-// ReadFrom satisfies the io.ReaderFrom interface.
-func (a *AssetID) ReadFrom(r io.Reader) (int64, error) { return (*Hash)(a).ReadFrom(r) }
-
-// IsZero tells whether a Asset pointer is nil or points to an all-zero hash.
-func (a *AssetID) IsZero() bool { return (*Hash)(a).IsZero() }
-
-// ComputeAssetID calculate the asset id from AssetDefinition
-func (ad *AssetDefinition) ComputeAssetID() (assetID AssetID) {
-       h := sha3pool.Get256()
-       defer sha3pool.Put256(h)
-       writeForHash(h, *ad) // error is impossible
-       var b [32]byte
-       h.Read(b[:]) // error is impossible
-       return NewAssetID(b)
-}
-
-// ComputeAssetID implement the assetID calculate logic
-func ComputeAssetID(prog []byte, vmVersion uint64, data *Hash) AssetID {
-       def := &AssetDefinition{
-               IssuanceProgram: &Program{
-                       VmVersion: vmVersion,
-                       Code:      prog,
-               },
-               Data: data,
-       }
-       return def.ComputeAssetID()
-}
-
-// ReadFrom read the AssetAmount from the bytes
-func (a *AssetAmount) ReadFrom(r *blockchain.Reader) (err error) {
-       var assetID AssetID
-       if _, err = assetID.ReadFrom(r); err != nil {
-               return err
-       }
-       a.AssetId = &assetID
-       a.Amount, err = blockchain.ReadVarint63(r)
-       return err
-}
-
-// WriteTo convert struct to byte and write to io
-func (a AssetAmount) WriteTo(w io.Writer) (int64, error) {
-       n, err := a.AssetId.WriteTo(w)
-       if err != nil {
-               return n, err
-       }
-       n2, err := blockchain.WriteVarint63(w, a.Amount)
-       return n + int64(n2), err
-}
-
-// Equal check does two AssetAmount have same assetID and amount
-func (a *AssetAmount) Equal(other *AssetAmount) (eq bool, err error) {
-       if a == nil || other == nil {
-               return false, errors.New("empty asset amount")
-       }
-       if a.AssetId == nil || other.AssetId == nil {
-               return false, errors.New("empty asset id")
-       }
-       return a.Amount == other.Amount && *a.AssetId == *other.AssetId, nil
-}
diff --git a/protocol/bc/types/bytom/asset_test.go b/protocol/bc/types/bytom/asset_test.go
deleted file mode 100644 (file)
index 19fff66..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-package bytom
-
-import (
-       "testing"
-
-       "golang.org/x/crypto/sha3"
-)
-
-func TestComputeAssetID(t *testing.T) {
-       issuanceScript := []byte{1}
-       assetID := ComputeAssetID(issuanceScript, 1, &EmptyStringHash)
-
-       unhashed := append([]byte{})
-       unhashed = append(unhashed, []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}...) // vmVersion
-       unhashed = append(unhashed, 0x01)                                                      // length of issuanceScript
-       unhashed = append(unhashed, issuanceScript...)
-       unhashed = append(unhashed, EmptyStringHash.Bytes()...)
-
-       if want := NewAssetID(sha3.Sum256(unhashed)); assetID != want {
-               t.Errorf("asset id = %x want %x", assetID.Bytes(), want.Bytes())
-       }
-}
-
-var assetIDSink AssetID
-
-func BenchmarkComputeAssetID(b *testing.B) {
-       var (
-               issuanceScript = []byte{5}
-       )
-
-       for i := 0; i < b.N; i++ {
-               assetIDSink = ComputeAssetID(issuanceScript, 1, &EmptyStringHash)
-       }
-}
diff --git a/protocol/bc/types/bytom/bc.pb.go b/protocol/bc/types/bytom/bc.pb.go
deleted file mode 100644 (file)
index a560afe..0000000
+++ /dev/null
@@ -1,725 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: bc.proto
-
-/*
-Package bytom is a generated protocol buffer package.
-
-It is generated from these files:
-       bc.proto
-
-It has these top-level messages:
-       Hash
-       Program
-       AssetID
-       AssetAmount
-       AssetDefinition
-       ValueSource
-       ValueDestination
-       BlockHeader
-       TxHeader
-       TxVerifyResult
-       TransactionStatus
-       Mux
-       Coinbase
-       Output
-       Retirement
-       Issuance
-       Spend
-*/
-package bytom
-
-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
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the proto package it is being compiled against.
-// A compilation error at this line likely means your copy of the
-// proto package needs to be updated.
-const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type Hash struct {
-       V0 uint64 `protobuf:"fixed64,1,opt,name=v0" json:"v0,omitempty"`
-       V1 uint64 `protobuf:"fixed64,2,opt,name=v1" json:"v1,omitempty"`
-       V2 uint64 `protobuf:"fixed64,3,opt,name=v2" json:"v2,omitempty"`
-       V3 uint64 `protobuf:"fixed64,4,opt,name=v3" json:"v3,omitempty"`
-}
-
-func (m *Hash) Reset()                    { *m = Hash{} }
-func (m *Hash) String() string            { return proto.CompactTextString(m) }
-func (*Hash) ProtoMessage()               {}
-func (*Hash) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-func (m *Hash) GetV0() uint64 {
-       if m != nil {
-               return m.V0
-       }
-       return 0
-}
-
-func (m *Hash) GetV1() uint64 {
-       if m != nil {
-               return m.V1
-       }
-       return 0
-}
-
-func (m *Hash) GetV2() uint64 {
-       if m != nil {
-               return m.V2
-       }
-       return 0
-}
-
-func (m *Hash) GetV3() uint64 {
-       if m != nil {
-               return m.V3
-       }
-       return 0
-}
-
-type Program struct {
-       VmVersion uint64 `protobuf:"varint,1,opt,name=vm_version,json=vmVersion" json:"vm_version,omitempty"`
-       Code      []byte `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
-}
-
-func (m *Program) Reset()                    { *m = Program{} }
-func (m *Program) String() string            { return proto.CompactTextString(m) }
-func (*Program) ProtoMessage()               {}
-func (*Program) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
-
-func (m *Program) GetVmVersion() uint64 {
-       if m != nil {
-               return m.VmVersion
-       }
-       return 0
-}
-
-func (m *Program) GetCode() []byte {
-       if m != nil {
-               return m.Code
-       }
-       return nil
-}
-
-// This message type duplicates Hash, above. One alternative is to
-// embed a Hash inside an AssetID. But it's useful for AssetID to be
-// plain old data (without pointers). Another alternative is use Hash
-// in any protobuf types where an AssetID is called for, but it's
-// preferable to have type safety.
-type AssetID struct {
-       V0 uint64 `protobuf:"fixed64,1,opt,name=v0" json:"v0,omitempty"`
-       V1 uint64 `protobuf:"fixed64,2,opt,name=v1" json:"v1,omitempty"`
-       V2 uint64 `protobuf:"fixed64,3,opt,name=v2" json:"v2,omitempty"`
-       V3 uint64 `protobuf:"fixed64,4,opt,name=v3" json:"v3,omitempty"`
-}
-
-func (m *AssetID) Reset()                    { *m = AssetID{} }
-func (m *AssetID) String() string            { return proto.CompactTextString(m) }
-func (*AssetID) ProtoMessage()               {}
-func (*AssetID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
-
-func (m *AssetID) GetV0() uint64 {
-       if m != nil {
-               return m.V0
-       }
-       return 0
-}
-
-func (m *AssetID) GetV1() uint64 {
-       if m != nil {
-               return m.V1
-       }
-       return 0
-}
-
-func (m *AssetID) GetV2() uint64 {
-       if m != nil {
-               return m.V2
-       }
-       return 0
-}
-
-func (m *AssetID) GetV3() uint64 {
-       if m != nil {
-               return m.V3
-       }
-       return 0
-}
-
-type AssetAmount struct {
-       AssetId *AssetID `protobuf:"bytes,1,opt,name=asset_id,json=assetId" json:"asset_id,omitempty"`
-       Amount  uint64   `protobuf:"varint,2,opt,name=amount" json:"amount,omitempty"`
-}
-
-func (m *AssetAmount) Reset()                    { *m = AssetAmount{} }
-func (m *AssetAmount) String() string            { return proto.CompactTextString(m) }
-func (*AssetAmount) ProtoMessage()               {}
-func (*AssetAmount) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
-
-func (m *AssetAmount) GetAssetId() *AssetID {
-       if m != nil {
-               return m.AssetId
-       }
-       return nil
-}
-
-func (m *AssetAmount) GetAmount() uint64 {
-       if m != nil {
-               return m.Amount
-       }
-       return 0
-}
-
-type AssetDefinition struct {
-       IssuanceProgram *Program `protobuf:"bytes,1,opt,name=issuance_program,json=issuanceProgram" json:"issuance_program,omitempty"`
-       Data            *Hash    `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"`
-}
-
-func (m *AssetDefinition) Reset()                    { *m = AssetDefinition{} }
-func (m *AssetDefinition) String() string            { return proto.CompactTextString(m) }
-func (*AssetDefinition) ProtoMessage()               {}
-func (*AssetDefinition) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
-
-func (m *AssetDefinition) GetIssuanceProgram() *Program {
-       if m != nil {
-               return m.IssuanceProgram
-       }
-       return nil
-}
-
-func (m *AssetDefinition) GetData() *Hash {
-       if m != nil {
-               return m.Data
-       }
-       return nil
-}
-
-type ValueSource struct {
-       Ref      *Hash        `protobuf:"bytes,1,opt,name=ref" json:"ref,omitempty"`
-       Value    *AssetAmount `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
-       Position uint64       `protobuf:"varint,3,opt,name=position" json:"position,omitempty"`
-}
-
-func (m *ValueSource) Reset()                    { *m = ValueSource{} }
-func (m *ValueSource) String() string            { return proto.CompactTextString(m) }
-func (*ValueSource) ProtoMessage()               {}
-func (*ValueSource) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
-
-func (m *ValueSource) GetRef() *Hash {
-       if m != nil {
-               return m.Ref
-       }
-       return nil
-}
-
-func (m *ValueSource) GetValue() *AssetAmount {
-       if m != nil {
-               return m.Value
-       }
-       return nil
-}
-
-func (m *ValueSource) GetPosition() uint64 {
-       if m != nil {
-               return m.Position
-       }
-       return 0
-}
-
-type ValueDestination struct {
-       Ref      *Hash        `protobuf:"bytes,1,opt,name=ref" json:"ref,omitempty"`
-       Value    *AssetAmount `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
-       Position uint64       `protobuf:"varint,3,opt,name=position" json:"position,omitempty"`
-}
-
-func (m *ValueDestination) Reset()                    { *m = ValueDestination{} }
-func (m *ValueDestination) String() string            { return proto.CompactTextString(m) }
-func (*ValueDestination) ProtoMessage()               {}
-func (*ValueDestination) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
-
-func (m *ValueDestination) GetRef() *Hash {
-       if m != nil {
-               return m.Ref
-       }
-       return nil
-}
-
-func (m *ValueDestination) GetValue() *AssetAmount {
-       if m != nil {
-               return m.Value
-       }
-       return nil
-}
-
-func (m *ValueDestination) GetPosition() uint64 {
-       if m != nil {
-               return m.Position
-       }
-       return 0
-}
-
-type BlockHeader struct {
-       Version               uint64             `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
-       Height                uint64             `protobuf:"varint,2,opt,name=height" json:"height,omitempty"`
-       PreviousBlockId       *Hash              `protobuf:"bytes,3,opt,name=previous_block_id,json=previousBlockId" json:"previous_block_id,omitempty"`
-       Timestamp             uint64             `protobuf:"varint,4,opt,name=timestamp" json:"timestamp,omitempty"`
-       TransactionsRoot      *Hash              `protobuf:"bytes,5,opt,name=transactions_root,json=transactionsRoot" json:"transactions_root,omitempty"`
-       TransactionStatusHash *Hash              `protobuf:"bytes,6,opt,name=transaction_status_hash,json=transactionStatusHash" json:"transaction_status_hash,omitempty"`
-       Nonce                 uint64             `protobuf:"varint,7,opt,name=nonce" json:"nonce,omitempty"`
-       Bits                  uint64             `protobuf:"varint,8,opt,name=bits" json:"bits,omitempty"`
-       TransactionStatus     *TransactionStatus `protobuf:"bytes,9,opt,name=transaction_status,json=transactionStatus" json:"transaction_status,omitempty"`
-}
-
-func (m *BlockHeader) Reset()                    { *m = BlockHeader{} }
-func (m *BlockHeader) String() string            { return proto.CompactTextString(m) }
-func (*BlockHeader) ProtoMessage()               {}
-func (*BlockHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
-
-func (m *BlockHeader) GetVersion() uint64 {
-       if m != nil {
-               return m.Version
-       }
-       return 0
-}
-
-func (m *BlockHeader) GetHeight() uint64 {
-       if m != nil {
-               return m.Height
-       }
-       return 0
-}
-
-func (m *BlockHeader) GetPreviousBlockId() *Hash {
-       if m != nil {
-               return m.PreviousBlockId
-       }
-       return nil
-}
-
-func (m *BlockHeader) GetTimestamp() uint64 {
-       if m != nil {
-               return m.Timestamp
-       }
-       return 0
-}
-
-func (m *BlockHeader) GetTransactionsRoot() *Hash {
-       if m != nil {
-               return m.TransactionsRoot
-       }
-       return nil
-}
-
-func (m *BlockHeader) GetTransactionStatusHash() *Hash {
-       if m != nil {
-               return m.TransactionStatusHash
-       }
-       return nil
-}
-
-func (m *BlockHeader) GetNonce() uint64 {
-       if m != nil {
-               return m.Nonce
-       }
-       return 0
-}
-
-func (m *BlockHeader) GetBits() uint64 {
-       if m != nil {
-               return m.Bits
-       }
-       return 0
-}
-
-func (m *BlockHeader) GetTransactionStatus() *TransactionStatus {
-       if m != nil {
-               return m.TransactionStatus
-       }
-       return nil
-}
-
-type TxHeader struct {
-       Version        uint64  `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
-       SerializedSize uint64  `protobuf:"varint,2,opt,name=serialized_size,json=serializedSize" json:"serialized_size,omitempty"`
-       TimeRange      uint64  `protobuf:"varint,3,opt,name=time_range,json=timeRange" json:"time_range,omitempty"`
-       ResultIds      []*Hash `protobuf:"bytes,4,rep,name=result_ids,json=resultIds" json:"result_ids,omitempty"`
-}
-
-func (m *TxHeader) Reset()                    { *m = TxHeader{} }
-func (m *TxHeader) String() string            { return proto.CompactTextString(m) }
-func (*TxHeader) ProtoMessage()               {}
-func (*TxHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
-
-func (m *TxHeader) GetVersion() uint64 {
-       if m != nil {
-               return m.Version
-       }
-       return 0
-}
-
-func (m *TxHeader) GetSerializedSize() uint64 {
-       if m != nil {
-               return m.SerializedSize
-       }
-       return 0
-}
-
-func (m *TxHeader) GetTimeRange() uint64 {
-       if m != nil {
-               return m.TimeRange
-       }
-       return 0
-}
-
-func (m *TxHeader) GetResultIds() []*Hash {
-       if m != nil {
-               return m.ResultIds
-       }
-       return nil
-}
-
-type TxVerifyResult struct {
-       StatusFail bool `protobuf:"varint,1,opt,name=status_fail,json=statusFail" json:"status_fail,omitempty"`
-}
-
-func (m *TxVerifyResult) Reset()                    { *m = TxVerifyResult{} }
-func (m *TxVerifyResult) String() string            { return proto.CompactTextString(m) }
-func (*TxVerifyResult) ProtoMessage()               {}
-func (*TxVerifyResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
-
-func (m *TxVerifyResult) GetStatusFail() bool {
-       if m != nil {
-               return m.StatusFail
-       }
-       return false
-}
-
-type TransactionStatus struct {
-       Version      uint64            `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
-       VerifyStatus []*TxVerifyResult `protobuf:"bytes,2,rep,name=verify_status,json=verifyStatus" json:"verify_status,omitempty"`
-}
-
-func (m *TransactionStatus) Reset()                    { *m = TransactionStatus{} }
-func (m *TransactionStatus) String() string            { return proto.CompactTextString(m) }
-func (*TransactionStatus) ProtoMessage()               {}
-func (*TransactionStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
-
-func (m *TransactionStatus) GetVersion() uint64 {
-       if m != nil {
-               return m.Version
-       }
-       return 0
-}
-
-func (m *TransactionStatus) GetVerifyStatus() []*TxVerifyResult {
-       if m != nil {
-               return m.VerifyStatus
-       }
-       return nil
-}
-
-type Mux struct {
-       Sources             []*ValueSource      `protobuf:"bytes,1,rep,name=sources" json:"sources,omitempty"`
-       Program             *Program            `protobuf:"bytes,2,opt,name=program" json:"program,omitempty"`
-       WitnessDestinations []*ValueDestination `protobuf:"bytes,3,rep,name=witness_destinations,json=witnessDestinations" json:"witness_destinations,omitempty"`
-       WitnessArguments    [][]byte            `protobuf:"bytes,4,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
-}
-
-func (m *Mux) Reset()                    { *m = Mux{} }
-func (m *Mux) String() string            { return proto.CompactTextString(m) }
-func (*Mux) ProtoMessage()               {}
-func (*Mux) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
-
-func (m *Mux) GetSources() []*ValueSource {
-       if m != nil {
-               return m.Sources
-       }
-       return nil
-}
-
-func (m *Mux) GetProgram() *Program {
-       if m != nil {
-               return m.Program
-       }
-       return nil
-}
-
-func (m *Mux) GetWitnessDestinations() []*ValueDestination {
-       if m != nil {
-               return m.WitnessDestinations
-       }
-       return nil
-}
-
-func (m *Mux) GetWitnessArguments() [][]byte {
-       if m != nil {
-               return m.WitnessArguments
-       }
-       return nil
-}
-
-type Coinbase struct {
-       WitnessDestination *ValueDestination `protobuf:"bytes,1,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
-       Arbitrary          []byte            `protobuf:"bytes,2,opt,name=arbitrary,proto3" json:"arbitrary,omitempty"`
-}
-
-func (m *Coinbase) Reset()                    { *m = Coinbase{} }
-func (m *Coinbase) String() string            { return proto.CompactTextString(m) }
-func (*Coinbase) ProtoMessage()               {}
-func (*Coinbase) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
-
-func (m *Coinbase) GetWitnessDestination() *ValueDestination {
-       if m != nil {
-               return m.WitnessDestination
-       }
-       return nil
-}
-
-func (m *Coinbase) GetArbitrary() []byte {
-       if m != nil {
-               return m.Arbitrary
-       }
-       return nil
-}
-
-type Output struct {
-       Source         *ValueSource `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
-       ControlProgram *Program     `protobuf:"bytes,2,opt,name=control_program,json=controlProgram" json:"control_program,omitempty"`
-       Ordinal        uint64       `protobuf:"varint,3,opt,name=ordinal" json:"ordinal,omitempty"`
-}
-
-func (m *Output) Reset()                    { *m = Output{} }
-func (m *Output) String() string            { return proto.CompactTextString(m) }
-func (*Output) ProtoMessage()               {}
-func (*Output) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
-
-func (m *Output) GetSource() *ValueSource {
-       if m != nil {
-               return m.Source
-       }
-       return nil
-}
-
-func (m *Output) GetControlProgram() *Program {
-       if m != nil {
-               return m.ControlProgram
-       }
-       return nil
-}
-
-func (m *Output) GetOrdinal() uint64 {
-       if m != nil {
-               return m.Ordinal
-       }
-       return 0
-}
-
-type Retirement struct {
-       Source  *ValueSource `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
-       Ordinal uint64       `protobuf:"varint,2,opt,name=ordinal" json:"ordinal,omitempty"`
-}
-
-func (m *Retirement) Reset()                    { *m = Retirement{} }
-func (m *Retirement) String() string            { return proto.CompactTextString(m) }
-func (*Retirement) ProtoMessage()               {}
-func (*Retirement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
-
-func (m *Retirement) GetSource() *ValueSource {
-       if m != nil {
-               return m.Source
-       }
-       return nil
-}
-
-func (m *Retirement) GetOrdinal() uint64 {
-       if m != nil {
-               return m.Ordinal
-       }
-       return 0
-}
-
-type Issuance struct {
-       NonceHash              *Hash             `protobuf:"bytes,1,opt,name=nonce_hash,json=nonceHash" json:"nonce_hash,omitempty"`
-       Value                  *AssetAmount      `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
-       WitnessDestination     *ValueDestination `protobuf:"bytes,3,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
-       WitnessAssetDefinition *AssetDefinition  `protobuf:"bytes,4,opt,name=witness_asset_definition,json=witnessAssetDefinition" json:"witness_asset_definition,omitempty"`
-       WitnessArguments       [][]byte          `protobuf:"bytes,5,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
-       Ordinal                uint64            `protobuf:"varint,6,opt,name=ordinal" json:"ordinal,omitempty"`
-}
-
-func (m *Issuance) Reset()                    { *m = Issuance{} }
-func (m *Issuance) String() string            { return proto.CompactTextString(m) }
-func (*Issuance) ProtoMessage()               {}
-func (*Issuance) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
-
-func (m *Issuance) GetNonceHash() *Hash {
-       if m != nil {
-               return m.NonceHash
-       }
-       return nil
-}
-
-func (m *Issuance) GetValue() *AssetAmount {
-       if m != nil {
-               return m.Value
-       }
-       return nil
-}
-
-func (m *Issuance) GetWitnessDestination() *ValueDestination {
-       if m != nil {
-               return m.WitnessDestination
-       }
-       return nil
-}
-
-func (m *Issuance) GetWitnessAssetDefinition() *AssetDefinition {
-       if m != nil {
-               return m.WitnessAssetDefinition
-       }
-       return nil
-}
-
-func (m *Issuance) GetWitnessArguments() [][]byte {
-       if m != nil {
-               return m.WitnessArguments
-       }
-       return nil
-}
-
-func (m *Issuance) GetOrdinal() uint64 {
-       if m != nil {
-               return m.Ordinal
-       }
-       return 0
-}
-
-type Spend struct {
-       SpentOutputId      *Hash             `protobuf:"bytes,1,opt,name=spent_output_id,json=spentOutputId" json:"spent_output_id,omitempty"`
-       WitnessDestination *ValueDestination `protobuf:"bytes,2,opt,name=witness_destination,json=witnessDestination" json:"witness_destination,omitempty"`
-       WitnessArguments   [][]byte          `protobuf:"bytes,3,rep,name=witness_arguments,json=witnessArguments,proto3" json:"witness_arguments,omitempty"`
-       Ordinal            uint64            `protobuf:"varint,4,opt,name=ordinal" json:"ordinal,omitempty"`
-}
-
-func (m *Spend) Reset()                    { *m = Spend{} }
-func (m *Spend) String() string            { return proto.CompactTextString(m) }
-func (*Spend) ProtoMessage()               {}
-func (*Spend) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
-
-func (m *Spend) GetSpentOutputId() *Hash {
-       if m != nil {
-               return m.SpentOutputId
-       }
-       return nil
-}
-
-func (m *Spend) GetWitnessDestination() *ValueDestination {
-       if m != nil {
-               return m.WitnessDestination
-       }
-       return nil
-}
-
-func (m *Spend) GetWitnessArguments() [][]byte {
-       if m != nil {
-               return m.WitnessArguments
-       }
-       return nil
-}
-
-func (m *Spend) GetOrdinal() uint64 {
-       if m != nil {
-               return m.Ordinal
-       }
-       return 0
-}
-
-func init() {
-       proto.RegisterType((*Hash)(nil), "bytom.Hash")
-       proto.RegisterType((*Program)(nil), "bytom.Program")
-       proto.RegisterType((*AssetID)(nil), "bytom.AssetID")
-       proto.RegisterType((*AssetAmount)(nil), "bytom.AssetAmount")
-       proto.RegisterType((*AssetDefinition)(nil), "bytom.AssetDefinition")
-       proto.RegisterType((*ValueSource)(nil), "bytom.ValueSource")
-       proto.RegisterType((*ValueDestination)(nil), "bytom.ValueDestination")
-       proto.RegisterType((*BlockHeader)(nil), "bytom.BlockHeader")
-       proto.RegisterType((*TxHeader)(nil), "bytom.TxHeader")
-       proto.RegisterType((*TxVerifyResult)(nil), "bytom.TxVerifyResult")
-       proto.RegisterType((*TransactionStatus)(nil), "bytom.TransactionStatus")
-       proto.RegisterType((*Mux)(nil), "bytom.Mux")
-       proto.RegisterType((*Coinbase)(nil), "bytom.Coinbase")
-       proto.RegisterType((*Output)(nil), "bytom.Output")
-       proto.RegisterType((*Retirement)(nil), "bytom.Retirement")
-       proto.RegisterType((*Issuance)(nil), "bytom.Issuance")
-       proto.RegisterType((*Spend)(nil), "bytom.Spend")
-}
-
-func init() { proto.RegisterFile("bc.proto", fileDescriptor0) }
-
-var fileDescriptor0 = []byte{
-       // 916 bytes of a gzipped FileDescriptorProto
-       0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6e, 0x1b, 0x37,
-       0x10, 0x86, 0xb4, 0xab, 0xbf, 0x91, 0x23, 0x59, 0x4c, 0xe2, 0x2c, 0x8a, 0x06, 0x09, 0xf6, 0x52,
-       0x37, 0x2d, 0x8c, 0x58, 0x3e, 0xa4, 0x2d, 0x7a, 0x71, 0x63, 0xa4, 0x56, 0x81, 0xa2, 0x06, 0x6d,
-       0xf8, 0xba, 0xa0, 0xb4, 0xb4, 0x45, 0x54, 0x4b, 0x0a, 0x24, 0x57, 0xb1, 0xfd, 0x02, 0xed, 0x23,
-       0xf4, 0x7d, 0x7a, 0xee, 0xb5, 0xcf, 0x53, 0x70, 0x96, 0x6b, 0xad, 0x2c, 0x39, 0xae, 0x51, 0xa0,
-       0x37, 0xcd, 0x70, 0x76, 0xbe, 0x99, 0x6f, 0xfe, 0x04, 0xed, 0xf1, 0x64, 0x6f, 0xae, 0x95, 0x55,
-       0xa4, 0x31, 0xbe, 0xb6, 0x2a, 0x8b, 0x3f, 0x40, 0x78, 0xcc, 0xcc, 0x94, 0xf4, 0xa0, 0xbe, 0x78,
-       0x1b, 0xd5, 0x5e, 0xd7, 0x76, 0x9b, 0xb4, 0xbe, 0x78, 0x8b, 0xf2, 0x7e, 0x54, 0xf7, 0xf2, 0x3e,
-       0xca, 0xc3, 0x28, 0xf0, 0xf2, 0x10, 0xe5, 0x83, 0x28, 0xf4, 0xf2, 0x41, 0xfc, 0x3d, 0xb4, 0x4e,
-       0xb4, 0xba, 0xd4, 0x2c, 0x23, 0x2f, 0x01, 0x16, 0x59, 0xb2, 0xe0, 0xda, 0x08, 0x25, 0xd1, 0x65,
-       0x48, 0x3b, 0x8b, 0xec, 0xbc, 0x50, 0x10, 0x02, 0xe1, 0x44, 0xa5, 0x1c, 0x7d, 0x6f, 0x51, 0xfc,
-       0x1d, 0x8f, 0xa0, 0x75, 0x68, 0x0c, 0xb7, 0xa3, 0xa3, 0xff, 0x1c, 0xc8, 0x09, 0x74, 0xd1, 0xd5,
-       0x61, 0xa6, 0x72, 0x69, 0xc9, 0x97, 0xd0, 0x66, 0x4e, 0x4c, 0x44, 0x8a, 0x4e, 0xbb, 0xc3, 0xde,
-       0x1e, 0x66, 0xbe, 0xe7, 0x01, 0x69, 0x0b, 0xdf, 0x47, 0x29, 0xd9, 0x81, 0x26, 0xc3, 0x8f, 0x10,
-       0x2d, 0xa4, 0x5e, 0x8a, 0x33, 0xe8, 0xa3, 0xed, 0x11, 0xbf, 0x10, 0x52, 0x58, 0x97, 0xc3, 0xb7,
-       0xb0, 0x2d, 0x8c, 0xc9, 0x99, 0x9c, 0xf0, 0x64, 0x5e, 0xa4, 0x7d, 0xc7, 0xbb, 0x27, 0x83, 0xf6,
-       0x4b, 0xbb, 0x92, 0x9d, 0x57, 0x10, 0xa6, 0xcc, 0x32, 0xc4, 0xe8, 0x0e, 0xbb, 0xde, 0xdc, 0xd5,
-       0x80, 0xe2, 0x43, 0xac, 0xa1, 0x7b, 0xce, 0x66, 0x39, 0x3f, 0x55, 0xb9, 0x9e, 0x70, 0xf2, 0x12,
-       0x02, 0xcd, 0x2f, 0xbc, 0xf7, 0x15, 0x73, 0xa7, 0x27, 0xbb, 0xd0, 0x58, 0x38, 0x6b, 0xef, 0x8f,
-       0x54, 0x93, 0x2b, 0x28, 0xa0, 0x85, 0x01, 0xf9, 0x0c, 0xda, 0x73, 0x65, 0x30, 0x7e, 0xa4, 0x2f,
-       0xa4, 0xb7, 0x72, 0xfc, 0x11, 0xb6, 0x11, 0xf3, 0x88, 0x1b, 0x2b, 0x24, 0xc3, 0x1c, 0xff, 0x17,
-       0xe0, 0xdf, 0x03, 0xe8, 0xfe, 0x30, 0x53, 0x93, 0x5f, 0x8f, 0x39, 0x4b, 0xb9, 0x26, 0x11, 0xb4,
-       0x56, 0x1b, 0xa7, 0x14, 0x5d, 0x75, 0xa6, 0x5c, 0x5c, 0x4e, 0x6f, 0xab, 0x53, 0x48, 0xe4, 0x1d,
-       0x0c, 0xe6, 0x9a, 0x2f, 0x84, 0xca, 0x4d, 0x32, 0x76, 0x9e, 0x5c, 0xa5, 0x83, 0xf5, 0xa0, 0xfb,
-       0xa5, 0x15, 0xc2, 0x8d, 0x52, 0xf2, 0x39, 0x74, 0xac, 0xc8, 0xb8, 0xb1, 0x2c, 0x9b, 0x63, 0xff,
-       0x84, 0x74, 0xa9, 0x20, 0xdf, 0xc0, 0xc0, 0x6a, 0x26, 0x0d, 0x9b, 0xb8, 0x38, 0x4d, 0xa2, 0x95,
-       0xb2, 0x51, 0x63, 0xdd, 0xed, 0x76, 0xd5, 0x8a, 0x2a, 0x65, 0xc9, 0x7b, 0x78, 0x51, 0xd1, 0x25,
-       0xc6, 0x32, 0x9b, 0x9b, 0x64, 0xca, 0xcc, 0x34, 0x6a, 0xae, 0x7f, 0xff, 0xbc, 0x62, 0x7b, 0x8a,
-       0xa6, 0x38, 0x8e, 0xcf, 0xa0, 0x21, 0x95, 0x9c, 0xf0, 0xa8, 0x85, 0x81, 0x15, 0x82, 0x1b, 0x9d,
-       0xb1, 0xb0, 0x26, 0x6a, 0xa3, 0x12, 0x7f, 0x93, 0x1f, 0x81, 0xac, 0xc3, 0x45, 0x1d, 0x44, 0x8a,
-       0x3c, 0xd2, 0xd9, 0x5d, 0x0c, 0x3a, 0x58, 0x83, 0x8d, 0xff, 0xa8, 0x41, 0xfb, 0xec, 0xea, 0xc1,
-       0x3a, 0x7c, 0x01, 0x7d, 0xc3, 0xb5, 0x60, 0x33, 0x71, 0xc3, 0xd3, 0xc4, 0x88, 0x1b, 0xee, 0x0b,
-       0xd2, 0x5b, 0xaa, 0x4f, 0xc5, 0x8d, 0x6b, 0x5c, 0x70, 0x74, 0x26, 0x9a, 0xc9, 0x4b, 0xee, 0x0b,
-       0x8f, 0x04, 0x53, 0xa7, 0x20, 0x6f, 0x00, 0x34, 0x37, 0xf9, 0xcc, 0x4d, 0xa6, 0x89, 0xc2, 0xd7,
-       0xc1, 0x5d, 0x66, 0x3a, 0xc5, 0xf3, 0x28, 0x35, 0xf1, 0x3e, 0xf4, 0xce, 0xae, 0xce, 0xb9, 0x16,
-       0x17, 0xd7, 0x14, 0x95, 0xe4, 0x15, 0x74, 0x3d, 0xb1, 0x17, 0x4c, 0xcc, 0x30, 0xc6, 0x36, 0x85,
-       0x42, 0xf5, 0x81, 0x89, 0x59, 0x2c, 0x60, 0xb0, 0x96, 0xf5, 0x27, 0xb2, 0xfa, 0x0e, 0x9e, 0x2c,
-       0xd0, 0x7f, 0x49, 0x60, 0x1d, 0x03, 0x7a, 0x5e, 0x12, 0xb8, 0x82, 0x4e, 0xb7, 0x0a, 0x5b, 0x4f,
-       0xdc, 0xdf, 0x35, 0x08, 0x7e, 0xce, 0xaf, 0xc8, 0xd7, 0xd0, 0x32, 0x38, 0xb3, 0x26, 0xaa, 0xe1,
-       0xd7, 0xe5, 0x4c, 0x54, 0xc6, 0x99, 0x96, 0x26, 0x64, 0x17, 0x5a, 0xe5, 0xe6, 0xa8, 0x6f, 0xdc,
-       0x1c, 0xe5, 0x33, 0xf9, 0x09, 0x9e, 0x7d, 0x14, 0x56, 0x72, 0x63, 0x92, 0x74, 0x39, 0x9f, 0x26,
-       0x0a, 0x10, 0xe4, 0x45, 0x15, 0xa4, 0x32, 0xbf, 0xf4, 0xa9, 0xff, 0xa8, 0xa2, 0x33, 0xe4, 0x2b,
-       0x18, 0x94, 0xbe, 0x98, 0xbe, 0xcc, 0x33, 0x2e, 0x6d, 0x41, 0xfe, 0x16, 0xdd, 0xf6, 0x0f, 0x87,
-       0xa5, 0x3e, 0xd6, 0xd0, 0x7e, 0xaf, 0x84, 0x1c, 0x33, 0xc3, 0xc9, 0x31, 0x3c, 0xdd, 0x10, 0x84,
-       0xdf, 0x0e, 0xf7, 0xc6, 0x40, 0xd6, 0x63, 0x70, 0x73, 0xc7, 0xf4, 0x58, 0x58, 0xcd, 0xf4, 0xb5,
-       0x3f, 0x02, 0x4b, 0x45, 0xfc, 0x5b, 0x0d, 0x9a, 0xbf, 0xe4, 0x76, 0x9e, 0x5b, 0xf2, 0x06, 0x9a,
-       0x05, 0x59, 0x1e, 0x65, 0x13, 0x9d, 0xde, 0x82, 0xbc, 0x83, 0xfe, 0x44, 0x49, 0xab, 0xd5, 0x2c,
-       0xf9, 0x34, 0xab, 0x3d, 0x6f, 0x56, 0xae, 0xe3, 0x08, 0x5a, 0x4a, 0xa7, 0x42, 0xb2, 0x99, 0x6f,
-       0xd1, 0x52, 0x8c, 0x29, 0x00, 0xe5, 0x56, 0x68, 0xee, 0xc8, 0x78, 0x54, 0x30, 0x15, 0x9f, 0xf5,
-       0x55, 0x9f, 0x7f, 0xd6, 0xa1, 0x3d, 0xf2, 0x07, 0xc1, 0x4d, 0x00, 0x8e, 0x75, 0xb1, 0x1b, 0x36,
-       0xec, 0xd9, 0x0e, 0x3e, 0xe3, 0x3e, 0xf8, 0xf7, 0xdb, 0xf6, 0x9e, 0x42, 0x05, 0x8f, 0x2f, 0xd4,
-       0x09, 0x44, 0xb7, 0xbd, 0x82, 0x27, 0x34, 0xbd, 0x3d, 0x80, 0xb8, 0x2f, 0xbb, 0xc3, 0x9d, 0x6a,
-       0x18, 0xcb, 0xf3, 0x48, 0x77, 0xca, 0x56, 0xba, 0x73, 0x36, 0x37, 0x76, 0x5f, 0x63, 0x73, 0xf7,
-       0x55, 0x59, 0x6c, 0xae, 0xb2, 0xf8, 0x57, 0x0d, 0x1a, 0xa7, 0x73, 0x2e, 0x53, 0x72, 0x00, 0x7d,
-       0x33, 0xe7, 0xd2, 0x26, 0x0a, 0x5b, 0x66, 0x79, 0xe4, 0x57, 0x78, 0x7c, 0x82, 0x36, 0x45, 0x57,
-       0x8d, 0xd2, 0xfb, 0x18, 0xaa, 0x3f, 0x9e, 0xa1, 0x8d, 0xf9, 0x04, 0x0f, 0xe7, 0x13, 0xae, 0xe4,
-       0x33, 0x6e, 0xe2, 0x3f, 0xb2, 0x83, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x91, 0x64, 0x55, 0x53,
-       0x9d, 0x09, 0x00, 0x00,
-}
diff --git a/protocol/bc/types/bytom/bc.proto b/protocol/bc/types/bytom/bc.proto
deleted file mode 100644 (file)
index 19b6883..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-syntax = "proto3";
-
-package bytom;
-
-message Hash {
-  fixed64 v0 = 1;
-  fixed64 v1 = 2;
-  fixed64 v2 = 3;
-  fixed64 v3 = 4;
-}
-
-message Program {
-  uint64 vm_version = 1;
-  bytes  code       = 2;
-}
-
-// This message type duplicates Hash, above. One alternative is to
-// embed a Hash inside an AssetID. But it's useful for AssetID to be
-// plain old data (without pointers). Another alternative is use Hash
-// in any protobuf types where an AssetID is called for, but it's
-// preferable to have type safety.
-message AssetID {
-  fixed64 v0 = 1;
-  fixed64 v1 = 2;
-  fixed64 v2 = 3;
-  fixed64 v3 = 4;
-}
-
-message AssetAmount {
-  AssetID asset_id = 1;
-  uint64  amount   = 2;
-}
-
-message AssetDefinition {
-  Program issuance_program = 1;
-  Hash    data             = 2;
-}
-
-message ValueSource {
-  Hash        ref      = 1;
-  AssetAmount value    = 2;
-  uint64      position = 3;
-}
-
-message ValueDestination {
-  Hash        ref      = 1;
-  AssetAmount value    = 2;
-  uint64      position = 3;
-}
-
-message BlockHeader {
-  uint64            version                 = 1;
-  uint64            height                  = 2;
-  Hash              previous_block_id       = 3;
-  uint64            timestamp               = 4;
-  Hash              transactions_root       = 5;
-  Hash              transaction_status_hash = 6;
-  uint64            nonce                   = 7;
-  uint64            bits                    = 8;
-  TransactionStatus transaction_status      = 9;
-}
-
-message TxHeader {
-  uint64        version         = 1;
-  uint64        serialized_size = 2;
-  uint64        time_range      = 3;
-  repeated Hash result_ids      = 4;
-}
-
-message TxVerifyResult {
-  bool status_fail = 1;
-}
-
-message TransactionStatus {
-  uint64                  version        = 1;
-  repeated TxVerifyResult verify_status  = 2;
-}
-
-message Mux {
-  repeated ValueSource      sources              = 1; // issuances, spends, and muxes
-  Program                   program              = 2;
-  repeated ValueDestination witness_destinations = 3; // outputs, retirements, and muxes
-  repeated bytes            witness_arguments    = 4;
-}
-
-message Coinbase {
-  ValueDestination witness_destination = 1;
-  bytes            arbitrary           = 2;
-}
-
-message Output {
-  ValueSource source          = 1;
-  Program     control_program = 2;
-  uint64      ordinal         = 3;
-}
-
-message Retirement {
-  ValueSource source   = 1;
-  uint64      ordinal  = 2;
-}
-
-message Issuance {
-  Hash             nonce_hash               = 1;
-  AssetAmount      value                    = 2;
-  ValueDestination witness_destination      = 3;
-  AssetDefinition  witness_asset_definition = 4;
-  repeated bytes   witness_arguments        = 5;
-  uint64           ordinal                  = 6;
-}
-
-message Spend {
-  Hash             spent_output_id     = 1;
-  ValueDestination witness_destination = 2;
-  repeated bytes   witness_arguments   = 3;
-  uint64           ordinal             = 4;
-}
\ No newline at end of file
index 4d1549e..38611a0 100644 (file)
@@ -1,8 +1,10 @@
 package bytom
 
+import "github.com/vapor/protocol/bc"
+
 // Block is block struct in bc level
 type Block struct {
-       *BlockHeader
-       ID           Hash
+       *bc.BytomBlockHeader
+       ID           bc.Hash
        Transactions []*Tx
 }
diff --git a/protocol/bc/types/bytom/coinbase.go b/protocol/bc/types/bytom/coinbase.go
deleted file mode 100644 (file)
index c47bf86..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-package bytom
-
-import "io"
-
-func (Coinbase) typ() string { return "coinbase1" }
-func (c *Coinbase) writeForHash(w io.Writer) {
-       mustWriteForHash(w, c.Arbitrary)
-}
-
-// SetDestination is support function for map tx
-func (c *Coinbase) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
-       c.WitnessDestination = &ValueDestination{
-               Ref:      id,
-               Value:    val,
-               Position: pos,
-       }
-}
-
-// NewCoinbase creates a new Coinbase.
-func NewCoinbase(arbitrary []byte) *Coinbase {
-       return &Coinbase{Arbitrary: arbitrary}
-}
diff --git a/protocol/bc/types/bytom/entry.go b/protocol/bc/types/bytom/entry.go
deleted file mode 100644 (file)
index cb7eaae..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-package bytom
-
-import (
-       "encoding/binary"
-       "fmt"
-       "io"
-       "reflect"
-
-       "github.com/golang/protobuf/proto"
-
-       "github.com/vapor/crypto/sha3pool"
-       "github.com/vapor/encoding/blockchain"
-       "github.com/vapor/errors"
-)
-
-// Entry is the interface implemented by each addressable unit in a
-// blockchain: transaction components such as spends, issuances,
-// outputs, and retirements (among others), plus blockheaders.
-type Entry interface {
-       proto.Message
-
-       // type produces a short human-readable string uniquely identifying
-       // the type of this entry.
-       typ() string
-
-       // writeForHash writes the entry's body for hashing.
-       writeForHash(w io.Writer)
-}
-
-var errInvalidValue = errors.New("invalid value")
-
-// EntryID computes the identifier of an entry, as the hash of its
-// body plus some metadata.
-func EntryID(e Entry) (hash Hash) {
-       if e == nil {
-               return hash
-       }
-
-       // Nil pointer; not the same as nil interface above. (See
-       // https://golang.org/doc/faq#nil_error.)
-       if v := reflect.ValueOf(e); v.Kind() == reflect.Ptr && v.IsNil() {
-               return hash
-       }
-
-       hasher := sha3pool.Get256()
-       defer sha3pool.Put256(hasher)
-
-       hasher.Write([]byte("entryid:"))
-       hasher.Write([]byte(e.typ()))
-       hasher.Write([]byte{':'})
-
-       bh := sha3pool.Get256()
-       defer sha3pool.Put256(bh)
-
-       e.writeForHash(bh)
-
-       var innerHash [32]byte
-       bh.Read(innerHash[:])
-
-       hasher.Write(innerHash[:])
-
-       hash.ReadFrom(hasher)
-       return hash
-}
-
-var byte32zero [32]byte
-
-// mustWriteForHash serializes the object c to the writer w, from which
-// presumably a hash can be extracted.
-//
-// This function may panic with an error from the underlying writer,
-// and may produce errors of its own if passed objects whose
-// hash-serialization formats are not specified. It MUST NOT produce
-// errors in other cases.
-func mustWriteForHash(w io.Writer, c interface{}) {
-       if err := writeForHash(w, c); err != nil {
-               panic(err)
-       }
-}
-
-func writeForHash(w io.Writer, c interface{}) error {
-       switch v := c.(type) {
-       case byte:
-               _, err := w.Write([]byte{v})
-               return errors.Wrap(err, "writing byte for hash")
-       case uint64:
-               buf := [8]byte{}
-               binary.LittleEndian.PutUint64(buf[:], v)
-               _, err := w.Write(buf[:])
-               return errors.Wrapf(err, "writing uint64 (%d) for hash", v)
-       case []byte:
-               _, err := blockchain.WriteVarstr31(w, v)
-               return errors.Wrapf(err, "writing []byte (len %d) for hash", len(v))
-       case [][]byte:
-               _, err := blockchain.WriteVarstrList(w, v)
-               return errors.Wrapf(err, "writing [][]byte (len %d) for hash", len(v))
-       case string:
-               _, err := blockchain.WriteVarstr31(w, []byte(v))
-               return errors.Wrapf(err, "writing string (len %d) for hash", len(v))
-       case *Hash:
-               if v == nil {
-                       _, err := w.Write(byte32zero[:])
-                       return errors.Wrap(err, "writing nil *Hash for hash")
-               }
-               _, err := w.Write(v.Bytes())
-               return errors.Wrap(err, "writing *Hash for hash")
-       case *AssetID:
-               if v == nil {
-                       _, err := w.Write(byte32zero[:])
-                       return errors.Wrap(err, "writing nil *AssetID for hash")
-               }
-               _, err := w.Write(v.Bytes())
-               return errors.Wrap(err, "writing *AssetID for hash")
-       case Hash:
-               _, err := v.WriteTo(w)
-               return errors.Wrap(err, "writing Hash for hash")
-       case AssetID:
-               _, err := v.WriteTo(w)
-               return errors.Wrap(err, "writing AssetID for hash")
-       }
-
-       // The two container types in the spec (List and Struct)
-       // correspond to slices and structs in Go. They can't be
-       // handled with type assertions, so we must use reflect.
-       switch v := reflect.ValueOf(c); v.Kind() {
-       case reflect.Ptr:
-               if v.IsNil() {
-                       return nil
-               }
-               elem := v.Elem()
-               return writeForHash(w, elem.Interface())
-       case reflect.Slice:
-               l := v.Len()
-               if _, err := blockchain.WriteVarint31(w, uint64(l)); err != nil {
-                       return errors.Wrapf(err, "writing slice (len %d) for hash", l)
-               }
-               for i := 0; i < l; i++ {
-                       c := v.Index(i)
-                       if !c.CanInterface() {
-                               return errInvalidValue
-                       }
-                       if err := writeForHash(w, c.Interface()); err != nil {
-                               return errors.Wrapf(err, "writing slice element %d for hash", i)
-                       }
-               }
-               return nil
-
-       case reflect.Struct:
-               typ := v.Type()
-               for i := 0; i < typ.NumField(); i++ {
-                       c := v.Field(i)
-                       if !c.CanInterface() {
-                               return errInvalidValue
-                       }
-                       if err := writeForHash(w, c.Interface()); err != nil {
-                               t := v.Type()
-                               f := t.Field(i)
-                               return errors.Wrapf(err, "writing struct field %d (%s.%s) for hash", i, t.Name(), f.Name)
-                       }
-               }
-               return nil
-       }
-
-       return errors.Wrap(fmt.Errorf("bad type %T", c))
-}
diff --git a/protocol/bc/types/bytom/entry_test.go b/protocol/bc/types/bytom/entry_test.go
deleted file mode 100644 (file)
index 9f88316..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package bytom
-
-import (
-       "reflect"
-       "testing"
-)
-
-func BenchmarkEntryID(b *testing.B) {
-       m := NewMux([]*ValueSource{{Position: 1}}, &Program{Code: []byte{1}, VmVersion: 1})
-
-       entries := []Entry{
-               NewIssuance(nil, &AssetAmount{}, 0),
-               m,
-               NewTxHeader(1, 1, 0, nil),
-               NewOutput(&ValueSource{}, &Program{Code: []byte{1}, VmVersion: 1}, 0),
-               NewRetirement(&ValueSource{}, 1),
-               NewSpend(&Hash{}, 0),
-       }
-
-       for _, e := range entries {
-               name := reflect.TypeOf(e).Elem().Name()
-               b.Run(name, func(b *testing.B) {
-                       for i := 0; i < b.N; i++ {
-                               EntryID(e)
-                       }
-               })
-       }
-}
index 9b12163..9fa860f 100644 (file)
@@ -3,6 +3,8 @@ package bytom
 import (
        "encoding/binary"
        "strings"
+
+       "github.com/vapor/protocol/bc"
 )
 
 //consensus variables
@@ -37,7 +39,7 @@ const (
 )
 
 // BTMAssetID is BTM's asset id, the soul asset of Bytom
-var BTMAssetID = &AssetID{
+var BTMAssetID = &bc.AssetID{
        V0: binary.BigEndian.Uint64([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}),
        V1: binary.BigEndian.Uint64([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}),
        V2: binary.BigEndian.Uint64([]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}),
@@ -45,7 +47,7 @@ var BTMAssetID = &AssetID{
 }
 
 // InitialSeed is SHA3-256 of Byte[0^32]
-var InitialSeed = &Hash{
+var InitialSeed = &bc.Hash{
        V0: uint64(11412844483649490393),
        V1: uint64(4614157290180302959),
        V2: uint64(1780246333311066183),
@@ -81,7 +83,7 @@ func IsBech32SegwitPrefix(prefix string, params *Params) bool {
 // and also prevents forks from old blocks.
 type Checkpoint struct {
        Height uint64
-       Hash   Hash
+       Hash   bc.Hash
 }
 
 // Params store the config for different network
@@ -107,14 +109,14 @@ var MainNetParams = Params{
        Name:            "main",
        Bech32HRPSegwit: "bm",
        Checkpoints: []Checkpoint{
-               {10000, NewHash([32]byte{0x93, 0xe1, 0xeb, 0x78, 0x21, 0xd2, 0xb4, 0xad, 0x0f, 0x5b, 0x1c, 0xea, 0x82, 0xe8, 0x43, 0xad, 0x8c, 0x09, 0x9a, 0xb6, 0x5d, 0x8f, 0x70, 0xc5, 0x84, 0xca, 0xa2, 0xdd, 0xf1, 0x74, 0x65, 0x2c})},
-               {20000, NewHash([32]byte{0x7d, 0x38, 0x61, 0xf3, 0x2c, 0xc0, 0x03, 0x81, 0xbb, 0xcd, 0x9a, 0x37, 0x6f, 0x10, 0x5d, 0xfe, 0x6f, 0xfe, 0x2d, 0xa5, 0xea, 0x88, 0xa5, 0xe3, 0x42, 0xed, 0xa1, 0x17, 0x9b, 0xa8, 0x0b, 0x7c})},
-               {30000, NewHash([32]byte{0x32, 0x36, 0x06, 0xd4, 0x27, 0x2e, 0x35, 0x24, 0x46, 0x26, 0x7b, 0xe0, 0xfa, 0x48, 0x10, 0xa4, 0x3b, 0xb2, 0x40, 0xf1, 0x09, 0x51, 0x5b, 0x22, 0x9f, 0xf3, 0xc3, 0x83, 0x28, 0xaa, 0x4a, 0x00})},
-               {40000, NewHash([32]byte{0x7f, 0xe2, 0xde, 0x11, 0x21, 0xf3, 0xa9, 0xa0, 0xee, 0x60, 0x8d, 0x7d, 0x4b, 0xea, 0xcc, 0x33, 0xfe, 0x41, 0x25, 0xdc, 0x2f, 0x26, 0xc2, 0xf2, 0x9c, 0x07, 0x17, 0xf9, 0xe4, 0x4f, 0x9d, 0x46})},
-               {50000, NewHash([32]byte{0x5e, 0xfb, 0xdf, 0xf5, 0x35, 0x38, 0xa6, 0x0b, 0x75, 0x32, 0x02, 0x61, 0x83, 0x54, 0x34, 0xff, 0x3e, 0x82, 0x2e, 0xf8, 0x64, 0xae, 0x2d, 0xc7, 0x6c, 0x9d, 0x5e, 0xbd, 0xa3, 0xd4, 0x50, 0xcf})},
-               {62000, NewHash([32]byte{0xd7, 0x39, 0x8f, 0x23, 0x57, 0xf9, 0x4c, 0xa0, 0x28, 0xa7, 0x00, 0x2b, 0x53, 0x9e, 0x51, 0x2d, 0x3e, 0xca, 0xc9, 0x22, 0x59, 0xfc, 0xd0, 0x3f, 0x67, 0x1a, 0x0a, 0xb1, 0x02, 0xbf, 0x2b, 0x03})},
-               {72000, NewHash([32]byte{0x66, 0x02, 0x31, 0x19, 0xf1, 0x60, 0x35, 0x61, 0xa4, 0xf1, 0x38, 0x04, 0xcc, 0xe4, 0x59, 0x8f, 0x55, 0x39, 0xba, 0x22, 0xf2, 0x6d, 0x90, 0xbf, 0xc1, 0x87, 0xef, 0x98, 0xcc, 0x70, 0x4d, 0x94})},
-               {83700, NewHash([32]byte{0x7f, 0x26, 0xc9, 0x11, 0xe8, 0x46, 0xd0, 0x6e, 0x36, 0xbb, 0xac, 0xce, 0x99, 0xa2, 0x19, 0x89, 0x3f, 0xf7, 0x84, 0x2a, 0xcb, 0x44, 0x7f, 0xbb, 0x0e, 0x3b, 0xa3, 0x68, 0xd6, 0x2b, 0xe8, 0x0d})},
+               {10000, bc.NewHash([32]byte{0x93, 0xe1, 0xeb, 0x78, 0x21, 0xd2, 0xb4, 0xad, 0x0f, 0x5b, 0x1c, 0xea, 0x82, 0xe8, 0x43, 0xad, 0x8c, 0x09, 0x9a, 0xb6, 0x5d, 0x8f, 0x70, 0xc5, 0x84, 0xca, 0xa2, 0xdd, 0xf1, 0x74, 0x65, 0x2c})},
+               {20000, bc.NewHash([32]byte{0x7d, 0x38, 0x61, 0xf3, 0x2c, 0xc0, 0x03, 0x81, 0xbb, 0xcd, 0x9a, 0x37, 0x6f, 0x10, 0x5d, 0xfe, 0x6f, 0xfe, 0x2d, 0xa5, 0xea, 0x88, 0xa5, 0xe3, 0x42, 0xed, 0xa1, 0x17, 0x9b, 0xa8, 0x0b, 0x7c})},
+               {30000, bc.NewHash([32]byte{0x32, 0x36, 0x06, 0xd4, 0x27, 0x2e, 0x35, 0x24, 0x46, 0x26, 0x7b, 0xe0, 0xfa, 0x48, 0x10, 0xa4, 0x3b, 0xb2, 0x40, 0xf1, 0x09, 0x51, 0x5b, 0x22, 0x9f, 0xf3, 0xc3, 0x83, 0x28, 0xaa, 0x4a, 0x00})},
+               {40000, bc.NewHash([32]byte{0x7f, 0xe2, 0xde, 0x11, 0x21, 0xf3, 0xa9, 0xa0, 0xee, 0x60, 0x8d, 0x7d, 0x4b, 0xea, 0xcc, 0x33, 0xfe, 0x41, 0x25, 0xdc, 0x2f, 0x26, 0xc2, 0xf2, 0x9c, 0x07, 0x17, 0xf9, 0xe4, 0x4f, 0x9d, 0x46})},
+               {50000, bc.NewHash([32]byte{0x5e, 0xfb, 0xdf, 0xf5, 0x35, 0x38, 0xa6, 0x0b, 0x75, 0x32, 0x02, 0x61, 0x83, 0x54, 0x34, 0xff, 0x3e, 0x82, 0x2e, 0xf8, 0x64, 0xae, 0x2d, 0xc7, 0x6c, 0x9d, 0x5e, 0xbd, 0xa3, 0xd4, 0x50, 0xcf})},
+               {62000, bc.NewHash([32]byte{0xd7, 0x39, 0x8f, 0x23, 0x57, 0xf9, 0x4c, 0xa0, 0x28, 0xa7, 0x00, 0x2b, 0x53, 0x9e, 0x51, 0x2d, 0x3e, 0xca, 0xc9, 0x22, 0x59, 0xfc, 0xd0, 0x3f, 0x67, 0x1a, 0x0a, 0xb1, 0x02, 0xbf, 0x2b, 0x03})},
+               {72000, bc.NewHash([32]byte{0x66, 0x02, 0x31, 0x19, 0xf1, 0x60, 0x35, 0x61, 0xa4, 0xf1, 0x38, 0x04, 0xcc, 0xe4, 0x59, 0x8f, 0x55, 0x39, 0xba, 0x22, 0xf2, 0x6d, 0x90, 0xbf, 0xc1, 0x87, 0xef, 0x98, 0xcc, 0x70, 0x4d, 0x94})},
+               {83700, bc.NewHash([32]byte{0x7f, 0x26, 0xc9, 0x11, 0xe8, 0x46, 0xd0, 0x6e, 0x36, 0xbb, 0xac, 0xce, 0x99, 0xa2, 0x19, 0x89, 0x3f, 0xf7, 0x84, 0x2a, 0xcb, 0x44, 0x7f, 0xbb, 0x0e, 0x3b, 0xa3, 0x68, 0xd6, 0x2b, 0xe8, 0x0d})},
        },
 }
 
@@ -123,8 +125,8 @@ var TestNetParams = Params{
        Name:            "test",
        Bech32HRPSegwit: "tm",
        Checkpoints: []Checkpoint{
-               {10303, NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c})},
-               {40000, NewHash([32]byte{0x6b, 0x13, 0x9a, 0x5b, 0x76, 0x77, 0x9b, 0xd4, 0x1c, 0xec, 0x53, 0x68, 0x44, 0xbf, 0xf4, 0x48, 0x94, 0x3d, 0x16, 0xe3, 0x9b, 0x2e, 0xe8, 0xa1, 0x0f, 0xa0, 0xbc, 0x7d, 0x2b, 0x17, 0x55, 0xfc})},
+               {10303, bc.NewHash([32]byte{0x3e, 0x94, 0x5d, 0x35, 0x70, 0x30, 0xd4, 0x3b, 0x3d, 0xe3, 0xdd, 0x80, 0x67, 0x29, 0x9a, 0x5e, 0x09, 0xf9, 0xfb, 0x2b, 0xad, 0x5f, 0x92, 0xc8, 0x69, 0xd1, 0x42, 0x39, 0x74, 0x9a, 0xd1, 0x1c})},
+               {40000, bc.NewHash([32]byte{0x6b, 0x13, 0x9a, 0x5b, 0x76, 0x77, 0x9b, 0xd4, 0x1c, 0xec, 0x53, 0x68, 0x44, 0xbf, 0xf4, 0x48, 0x94, 0x3d, 0x16, 0xe3, 0x9b, 0x2e, 0xe8, 0xa1, 0x0f, 0xa0, 0xbc, 0x7d, 0x2b, 0x17, 0x55, 0xfc})},
        },
 }
 
diff --git a/protocol/bc/types/bytom/hash.go b/protocol/bc/types/bytom/hash.go
deleted file mode 100644 (file)
index 23d3359..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-package bytom
-
-import (
-       "bytes"
-       "encoding/binary"
-       "encoding/hex"
-       "encoding/json"
-       "fmt"
-       "io"
-
-       "golang.org/x/crypto/sha3"
-)
-
-// EmptyStringHash represents a 256-bit hash.
-var EmptyStringHash = NewHash(sha3.Sum256(nil))
-
-// NewHash convert the input byte array to hash
-func NewHash(b32 [32]byte) (h Hash) {
-       h.V0 = binary.BigEndian.Uint64(b32[0:8])
-       h.V1 = binary.BigEndian.Uint64(b32[8:16])
-       h.V2 = binary.BigEndian.Uint64(b32[16:24])
-       h.V3 = binary.BigEndian.Uint64(b32[24:32])
-       return h
-}
-
-// Byte32 return the byte array representation
-func (h Hash) Byte32() (b32 [32]byte) {
-       binary.BigEndian.PutUint64(b32[0:8], h.V0)
-       binary.BigEndian.PutUint64(b32[8:16], h.V1)
-       binary.BigEndian.PutUint64(b32[16:24], h.V2)
-       binary.BigEndian.PutUint64(b32[24:32], h.V3)
-       return b32
-}
-
-// MarshalText satisfies the TextMarshaler interface.
-// It returns the bytes of h encoded in hex,
-// for formats that can't hold arbitrary binary data.
-// It never returns an error.
-func (h Hash) MarshalText() ([]byte, error) {
-       b := h.Byte32()
-       v := make([]byte, 64)
-       hex.Encode(v, b[:])
-       return v, nil
-}
-
-// UnmarshalText satisfies the TextUnmarshaler interface.
-// It decodes hex data from b into h.
-func (h *Hash) UnmarshalText(v []byte) error {
-       var b [32]byte
-       if len(v) != 64 {
-               return fmt.Errorf("bad length hash string %d", len(v))
-       }
-       _, err := hex.Decode(b[:], v)
-       *h = NewHash(b)
-       return err
-}
-
-// UnmarshalJSON satisfies the json.Unmarshaler interface.
-// If b is a JSON-encoded null, it copies the zero-value into h. Othwerwise, it
-// decodes hex data from b into h.
-func (h *Hash) UnmarshalJSON(b []byte) error {
-       if bytes.Equal(b, []byte("null")) {
-               *h = Hash{}
-               return nil
-       }
-       var s string
-       if err := json.Unmarshal(b, &s); err != nil {
-               return err
-       }
-       return h.UnmarshalText([]byte(s))
-}
-
-// Bytes returns the byte representation
-func (h Hash) Bytes() []byte {
-       b32 := h.Byte32()
-       return b32[:]
-}
-
-// WriteTo satisfies the io.WriterTo interface.
-func (h Hash) WriteTo(w io.Writer) (int64, error) {
-       n, err := w.Write(h.Bytes())
-       return int64(n), err
-}
-
-// ReadFrom satisfies the io.ReaderFrom interface.
-func (h *Hash) ReadFrom(r io.Reader) (int64, error) {
-       var b32 [32]byte
-       n, err := io.ReadFull(r, b32[:])
-       if err != nil {
-               return int64(n), err
-       }
-       *h = NewHash(b32)
-       return int64(n), nil
-}
-
-// IsZero tells whether a Hash pointer is nil or points to an all-zero
-// hash.
-func (h *Hash) IsZero() bool {
-       if h == nil {
-               return true
-       }
-       return *h == Hash{}
-}
diff --git a/protocol/bc/types/bytom/issuance.go b/protocol/bc/types/bytom/issuance.go
deleted file mode 100644 (file)
index 2e8542a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package bytom
-
-import "io"
-
-// Issuance is a source of new value on a blockchain. It satisfies the
-// Entry interface.
-
-func (Issuance) typ() string { return "issuance1" }
-func (iss *Issuance) writeForHash(w io.Writer) {
-       mustWriteForHash(w, iss.NonceHash)
-       mustWriteForHash(w, iss.Value)
-}
-
-// SetDestination will link the issuance to the output
-func (iss *Issuance) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
-       iss.WitnessDestination = &ValueDestination{
-               Ref:      id,
-               Value:    val,
-               Position: pos,
-       }
-}
-
-// NewIssuance creates a new Issuance.
-func NewIssuance(nonceHash *Hash, value *AssetAmount, ordinal uint64) *Issuance {
-       return &Issuance{
-               NonceHash: nonceHash,
-               Value:     value,
-               Ordinal:   ordinal,
-       }
-}
diff --git a/protocol/bc/types/bytom/mux.go b/protocol/bc/types/bytom/mux.go
deleted file mode 100644 (file)
index 61ed042..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-package bytom
-
-import "io"
-
-// Mux splits and combines value from one or more source entries,
-// making it available to one or more destination entries. It
-// satisfies the Entry interface.
-
-func (Mux) typ() string { return "mux1" }
-func (m *Mux) writeForHash(w io.Writer) {
-       mustWriteForHash(w, m.Sources)
-       mustWriteForHash(w, m.Program)
-}
-
-// NewMux creates a new Mux.
-func NewMux(sources []*ValueSource, program *Program) *Mux {
-       return &Mux{
-               Sources: sources,
-               Program: program,
-       }
-}
diff --git a/protocol/bc/types/bytom/output.go b/protocol/bc/types/bytom/output.go
deleted file mode 100644 (file)
index 8128039..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-package bytom
-
-import "io"
-
-// Output is the result of a transfer of value. The value it contains
-// may be accessed by a later Spend entry (if that entry can satisfy
-// the Output's ControlProgram). Output satisfies the Entry interface.
-//
-// (Not to be confused with the deprecated type TxOutput.)
-
-func (Output) typ() string { return "output1" }
-func (o *Output) writeForHash(w io.Writer) {
-       mustWriteForHash(w, o.Source)
-       mustWriteForHash(w, o.ControlProgram)
-}
-
-// NewOutput creates a new Output.
-func NewOutput(source *ValueSource, controlProgram *Program, ordinal uint64) *Output {
-       return &Output{
-               Source:         source,
-               ControlProgram: controlProgram,
-               Ordinal:        ordinal,
-       }
-}
diff --git a/protocol/bc/types/bytom/retirement.go b/protocol/bc/types/bytom/retirement.go
deleted file mode 100644 (file)
index 3aa9111..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-package bytom
-
-import "io"
-
-// Retirement is for the permanent removal of some value from a
-// blockchain. The value it contains can never be obtained by later
-// entries. Retirement satisfies the Entry interface.
-
-func (Retirement) typ() string { return "retirement1" }
-func (r *Retirement) writeForHash(w io.Writer) {
-       mustWriteForHash(w, r.Source)
-}
-
-// NewRetirement creates a new Retirement.
-func NewRetirement(source *ValueSource, ordinal uint64) *Retirement {
-       return &Retirement{
-               Source:  source,
-               Ordinal: ordinal,
-       }
-}
diff --git a/protocol/bc/types/bytom/spend.go b/protocol/bc/types/bytom/spend.go
deleted file mode 100644 (file)
index f4092d7..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package bytom
-
-import "io"
-
-// Spend accesses the value in a prior Output for transfer
-// elsewhere. It satisfies the Entry interface.
-//
-// (Not to be confused with the deprecated type SpendInput.)
-
-func (Spend) typ() string { return "spend1" }
-func (s *Spend) writeForHash(w io.Writer) {
-       mustWriteForHash(w, s.SpentOutputId)
-}
-
-// SetDestination will link the spend to the output
-func (s *Spend) SetDestination(id *Hash, val *AssetAmount, pos uint64) {
-       s.WitnessDestination = &ValueDestination{
-               Ref:      id,
-               Value:    val,
-               Position: pos,
-       }
-}
-
-// NewSpend creates a new Spend.
-func NewSpend(spentOutputID *Hash, ordinal uint64) *Spend {
-       return &Spend{
-               SpentOutputId: spentOutputID,
-               Ordinal:       ordinal,
-       }
-}
index 3b47c87..a5fa896 100644 (file)
@@ -3,21 +3,22 @@ package bytom
 import (
        "github.com/vapor/crypto/sha3pool"
        "github.com/vapor/errors"
+       "github.com/vapor/protocol/bc"
 )
 
 // Tx is a wrapper for the entries-based representation of a transaction.
 type Tx struct {
-       *TxHeader
-       ID       Hash
-       Entries  map[Hash]Entry
-       InputIDs []Hash // 1:1 correspondence with TxData.Inputs
+       *bc.TxHeader
+       ID       bc.Hash
+       Entries  map[bc.Hash]bc.Entry
+       InputIDs []bc.Hash // 1:1 correspondence with TxData.Inputs
 
-       SpentOutputIDs []Hash
-       GasInputIDs    []Hash
+       SpentOutputIDs []bc.Hash
+       GasInputIDs    []bc.Hash
 }
 
 // SigHash ...
-func (tx *Tx) SigHash(n uint32) (hash Hash) {
+func (tx *Tx) SigHash(n uint32) (hash bc.Hash) {
        hasher := sha3pool.Get256()
        defer sha3pool.Put256(hasher)
 
@@ -34,12 +35,12 @@ var (
 )
 
 // Output try to get the output entry by given hash
-func (tx *Tx) Output(id Hash) (*Output, error) {
+func (tx *Tx) Output(id bc.Hash) (*bc.Output, error) {
        e, ok := tx.Entries[id]
        if !ok || e == nil {
                return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
        }
-       o, ok := e.(*Output)
+       o, ok := e.(*bc.Output)
        if !ok {
                return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
        }
@@ -47,12 +48,12 @@ func (tx *Tx) Output(id Hash) (*Output, error) {
 }
 
 // Spend try to get the spend entry by given hash
-func (tx *Tx) Spend(id Hash) (*Spend, error) {
+func (tx *Tx) Spend(id bc.Hash) (*bc.Spend, error) {
        e, ok := tx.Entries[id]
        if !ok || e == nil {
                return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
        }
-       sp, ok := e.(*Spend)
+       sp, ok := e.(*bc.Spend)
        if !ok {
                return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
        }
@@ -60,12 +61,12 @@ func (tx *Tx) Spend(id Hash) (*Spend, error) {
 }
 
 // Issuance try to get the issuance entry by given hash
-func (tx *Tx) Issuance(id Hash) (*Issuance, error) {
+func (tx *Tx) Issuance(id bc.Hash) (*bc.Issuance, error) {
        e, ok := tx.Entries[id]
        if !ok || e == nil {
                return nil, errors.Wrapf(ErrMissingEntry, "id %x", id.Bytes())
        }
-       iss, ok := e.(*Issuance)
+       iss, ok := e.(*bc.Issuance)
        if !ok {
                return nil, errors.Wrapf(ErrEntryType, "entry %x has unexpected type %T", id.Bytes(), e)
        }
diff --git a/protocol/bc/types/bytom/tx_status.go b/protocol/bc/types/bytom/tx_status.go
deleted file mode 100644 (file)
index ac1aa58..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-package bytom
-
-import (
-       "encoding/json"
-       "errors"
-       "io"
-)
-
-const transactionStatusVersion = 1
-
-// NewTransactionStatus create a empty TransactionStatus struct
-func NewTransactionStatus() *TransactionStatus {
-       return &TransactionStatus{
-               Version:      transactionStatusVersion,
-               VerifyStatus: []*TxVerifyResult{},
-       }
-}
-
-// SetStatus set the tx status of given index
-func (ts *TransactionStatus) SetStatus(i int, gasOnly bool) error {
-       if i > len(ts.VerifyStatus) {
-               return errors.New("setStatus should be set one by one")
-       }
-
-       if i == len(ts.VerifyStatus) {
-               ts.VerifyStatus = append(ts.VerifyStatus, &TxVerifyResult{StatusFail: gasOnly})
-       } else {
-               ts.VerifyStatus[i].StatusFail = gasOnly
-       }
-       return nil
-}
-
-// GetStatus get the tx status of given index
-func (ts *TransactionStatus) GetStatus(i int) (bool, error) {
-       if i >= len(ts.VerifyStatus) {
-               return false, errors.New("GetStatus is out of range")
-       }
-
-       return ts.VerifyStatus[i].StatusFail, nil
-}
-
-// WriteTo will write TxVerifyResult struct to io.Writer
-func (tvr *TxVerifyResult) WriteTo(w io.Writer) (int64, error) {
-       bytes, err := json.Marshal(tvr)
-       if err != nil {
-               return 0, err
-       }
-
-       n, err := w.Write(bytes)
-       return int64(n), err
-}
diff --git a/protocol/bc/types/bytom/tx_status_test.go b/protocol/bc/types/bytom/tx_status_test.go
deleted file mode 100644 (file)
index 3fcb061..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-package bytom
-
-import (
-       "testing"
-)
-
-func TestSetBits(t *testing.T) {
-       cases := []struct {
-               op     map[int]bool
-               result []bool
-       }{
-               {
-                       op: map[int]bool{
-                               0: true,
-                       },
-                       result: []bool{true},
-               },
-               {
-                       op: map[int]bool{
-                               0: false,
-                       },
-                       result: []bool{false},
-               },
-               {
-                       op: map[int]bool{
-                               0: false,
-                               1: true,
-                       },
-                       result: []bool{false, true},
-               },
-               {
-                       op: map[int]bool{
-                               0: true,
-                               1: false,
-                       },
-                       result: []bool{true, false},
-               },
-               {
-                       op: map[int]bool{
-                               0: true,
-                               1: false,
-                               2: false,
-                               3: true,
-                               4: true,
-                               5: true,
-                               6: false,
-                               7: true,
-                               8: false,
-                               9: true,
-                       },
-                       result: []bool{true, false, false, true, true, true, false, true, false, true},
-               },
-       }
-
-       for ci, c := range cases {
-               ts := NewTransactionStatus()
-               for i := 0; i < len(c.op); i++ {
-                       if err := ts.SetStatus(i, c.op[i]); err != nil {
-                               t.Errorf("test case #%d, %t", ci, err)
-                       }
-               }
-
-               for i, v := range c.result {
-                       result, err := ts.GetStatus(i)
-                       if err != nil {
-                               t.Errorf("test case #%d, %t", ci, err)
-                       }
-                       if result != v {
-                               t.Errorf("bad result, %d want %t get %t", i, v, result)
-                       }
-               }
-       }
-}
diff --git a/protocol/bc/types/bytom/txheader.go b/protocol/bc/types/bytom/txheader.go
deleted file mode 100644 (file)
index 268cbee..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-package bytom
-
-import "io"
-
-// TxHeader contains header information for a transaction. Every
-// transaction on a blockchain contains exactly one TxHeader. The ID
-// of the TxHeader is the ID of the transaction. TxHeader satisfies
-// the Entry interface.
-
-func (TxHeader) typ() string { return "txheader" }
-func (h *TxHeader) writeForHash(w io.Writer) {
-       mustWriteForHash(w, h.Version)
-       mustWriteForHash(w, h.TimeRange)
-       mustWriteForHash(w, h.ResultIds)
-}
-
-// NewTxHeader creates an new TxHeader.
-func NewTxHeader(version, serializedSize, timeRange uint64, resultIDs []*Hash) *TxHeader {
-       return &TxHeader{
-               Version:        version,
-               SerializedSize: serializedSize,
-               TimeRange:      timeRange,
-               ResultIds:      resultIDs,
-       }
-}
index c7dfa5b..cd9cdd0 100644 (file)
@@ -4,18 +4,18 @@ import (
        "io"
 
        "github.com/vapor/encoding/blockchain"
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
 )
 
 // BlockCommitment store the TransactionsMerkleRoot && TransactionStatusHash
 type BlockCommitment struct {
        // TransactionsMerkleRoot is the root hash of the Merkle binary hash tree
        // formed by the hashes of all transactions included in the block.
-       TransactionsMerkleRoot bytom.Hash `json:"transaction_merkle_root"`
+       TransactionsMerkleRoot bc.Hash `json:"transaction_merkle_root"`
 
        // TransactionStatusHash is the root hash of the Merkle binary hash tree
        // formed by the hashes of all transaction verify results
-       TransactionStatusHash bytom.Hash `json:"transaction_status_hash"`
+       TransactionStatusHash bc.Hash `json:"transaction_status_hash"`
 }
 
 func (bc *BlockCommitment) readFrom(r *blockchain.Reader) error {
index 7f8dc02..c2bc036 100644 (file)
@@ -9,17 +9,17 @@ import (
        "github.com/vapor/encoding/blockchain"
        "github.com/vapor/encoding/bufpool"
        "github.com/vapor/errors"
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
 )
 
 // BlockHeader defines information about a block and is used in the Bytom
 type BlockHeader struct {
-       Version           uint64     // The version of the block.
-       Height            uint64     // The height of the block.
-       PreviousBlockHash bytom.Hash // The hash of the previous block.
-       Timestamp         uint64     // The time of the block in seconds.
-       Nonce             uint64     // Nonce used to generate the block.
-       Bits              uint64     // Difficulty target for the block.
+       Version           uint64  // The version of the block.
+       Height            uint64  // The height of the block.
+       PreviousBlockHash bc.Hash // The hash of the previous block.
+       Timestamp         uint64  // The time of the block in seconds.
+       Nonce             uint64  // Nonce used to generate the block.
+       Bits              uint64  // Difficulty target for the block.
        BlockCommitment
 }
 
@@ -29,7 +29,7 @@ func (bh *BlockHeader) Time() time.Time {
 }
 
 // Hash returns complete hash of the block header.
-func (bh *BlockHeader) Hash() bytom.Hash {
+func (bh *BlockHeader) Hash() bc.Hash {
        h, _ := mapBlockHeader(bh)
        return h
 }
diff --git a/protocol/bc/types/bytom/types/issuance.go b/protocol/bc/types/bytom/types/issuance.go
deleted file mode 100644 (file)
index baa6e75..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-package types
-
-import (
-       "github.com/vapor/crypto/sha3pool"
-       "github.com/vapor/protocol/bc/types/bytom"
-)
-
-// IssuanceInput satisfies the TypedInput interface and represents a issuance.
-type IssuanceInput struct {
-       Nonce  []byte
-       Amount uint64
-
-       AssetDefinition []byte
-       VMVersion       uint64
-       IssuanceProgram []byte
-       Arguments       [][]byte
-}
-
-// NewIssuanceInput create a new IssuanceInput struct.
-func NewIssuanceInput(nonce []byte, amount uint64, issuanceProgram []byte, arguments [][]byte, assetDefinition []byte) *TxInput {
-       return &TxInput{
-               AssetVersion: 1,
-               TypedInput: &IssuanceInput{
-                       Nonce:           nonce,
-                       Amount:          amount,
-                       AssetDefinition: assetDefinition,
-                       VMVersion:       1,
-                       IssuanceProgram: issuanceProgram,
-                       Arguments:       arguments,
-               },
-       }
-}
-
-// InputType is the interface function for return the input type.
-func (ii *IssuanceInput) InputType() uint8 { return IssuanceInputType }
-
-// AssetID calculate the assetID of the issuance input.
-func (ii *IssuanceInput) AssetID() bytom.AssetID {
-       defhash := ii.AssetDefinitionHash()
-       return bytom.ComputeAssetID(ii.IssuanceProgram, ii.VMVersion, &defhash)
-}
-
-// AssetDefinitionHash return the hash of the issuance asset definition.
-func (ii *IssuanceInput) AssetDefinitionHash() (defhash bytom.Hash) {
-       sha := sha3pool.Get256()
-       defer sha3pool.Put256(sha)
-       sha.Write(ii.AssetDefinition)
-       defhash.ReadFrom(sha)
-       return defhash
-}
-
-// NonceHash return the hash of the issuance asset definition.
-func (ii *IssuanceInput) NonceHash() (hash bytom.Hash) {
-       sha := sha3pool.Get256()
-       defer sha3pool.Put256(sha)
-       sha.Write(ii.Nonce)
-       hash.ReadFrom(sha)
-       return hash
-}
index 38d4f50..a878259 100644 (file)
@@ -1,6 +1,9 @@
 package types
 
 import (
+       "github.com/vapor/consensus"
+       "github.com/vapor/protocol/bc"
+       "github.com/vapor/protocol/bc/types"
        "github.com/vapor/protocol/bc/types/bytom"
        "github.com/vapor/protocol/vm"
        "github.com/vapor/protocol/vm/vmutil"
@@ -14,24 +17,24 @@ func MapTx(oldTx *TxData) *bytom.Tx {
                TxHeader: txHeader,
                ID:       txID,
                Entries:  entries,
-               InputIDs: make([]bytom.Hash, len(oldTx.Inputs)),
+               InputIDs: make([]bc.Hash, len(oldTx.Inputs)),
        }
 
-       spentOutputIDs := make(map[bytom.Hash]bool)
+       spentOutputIDs := make(map[bc.Hash]bool)
        for id, e := range entries {
                var ord uint64
                switch e := e.(type) {
-               case *bytom.Issuance:
+               case *bc.Issuance:
                        ord = e.Ordinal
 
-               case *bytom.Spend:
+               case *bc.Spend:
                        ord = e.Ordinal
                        spentOutputIDs[*e.SpentOutputId] = true
-                       if *e.WitnessDestination.Value.AssetId == *bytom.BTMAssetID {
+                       if *e.WitnessDestination.Value.AssetId == *consensus.BTMAssetID {
                                tx.GasInputIDs = append(tx.GasInputIDs, id)
                        }
 
-               case *bytom.Coinbase:
+               case *bc.Coinbase:
                        ord = 0
 
                default:
@@ -50,32 +53,32 @@ func MapTx(oldTx *TxData) *bytom.Tx {
        return tx
 }
 
-func mapTx(tx *TxData) (headerID bytom.Hash, hdr *bytom.TxHeader, entryMap map[bytom.Hash]bytom.Entry) {
-       entryMap = make(map[bytom.Hash]bytom.Entry)
-       addEntry := func(e bytom.Entry) bytom.Hash {
-               id := bytom.EntryID(e)
+func mapTx(tx *TxData) (headerID bc.Hash, hdr *bc.TxHeader, entryMap map[bc.Hash]bc.Entry) {
+       entryMap = make(map[bc.Hash]bc.Entry)
+       addEntry := func(e bc.Entry) bc.Hash {
+               id := bc.EntryID(e)
                entryMap[id] = e
                return id
        }
 
        var (
-               spends    []*bytom.Spend
-               issuances []*bytom.Issuance
-               coinbase  *bytom.Coinbase
+               spends    []*bc.Spend
+               issuances []*bc.Issuance
+               coinbase  *bc.Coinbase
        )
 
-       muxSources := make([]*bytom.ValueSource, len(tx.Inputs))
+       muxSources := make([]*bc.ValueSource, len(tx.Inputs))
        for i, input := range tx.Inputs {
                switch inp := input.TypedInput.(type) {
-               case *IssuanceInput:
+               case *types.IssuanceInput:
                        nonceHash := inp.NonceHash()
                        assetDefHash := inp.AssetDefinitionHash()
                        value := input.AssetAmount()
 
-                       issuance := bytom.NewIssuance(&nonceHash, &value, uint64(i))
-                       issuance.WitnessAssetDefinition = &bytom.AssetDefinition{
+                       issuance := bc.NewIssuance(&nonceHash, &value, uint64(i))
+                       issuance.WitnessAssetDefinition = &bc.AssetDefinition{
                                Data: &assetDefHash,
-                               IssuanceProgram: &bytom.Program{
+                               IssuanceProgram: &bc.Program{
                                        VmVersion: inp.VMVersion,
                                        Code:      inp.IssuanceProgram,
                                },
@@ -83,7 +86,7 @@ func mapTx(tx *TxData) (headerID bytom.Hash, hdr *bytom.TxHeader, entryMap map[b
                        issuance.WitnessArguments = inp.Arguments
                        issuanceID := addEntry(issuance)
 
-                       muxSources[i] = &bytom.ValueSource{
+                       muxSources[i] = &bc.ValueSource{
                                Ref:   &issuanceID,
                                Value: &value,
                        }
@@ -91,43 +94,43 @@ func mapTx(tx *TxData) (headerID bytom.Hash, hdr *bytom.TxHeader, entryMap map[b
 
                case *SpendInput:
                        // create entry for prevout
-                       prog := &bytom.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
-                       src := &bytom.ValueSource{
+                       prog := &bc.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
+                       src := &bc.ValueSource{
                                Ref:      &inp.SourceID,
                                Value:    &inp.AssetAmount,
                                Position: inp.SourcePosition,
                        }
-                       prevout := bytom.NewOutput(src, prog, 0) // ordinal doesn't matter for prevouts, only for result outputs
+                       prevout := bc.NewOutput(src, prog, 0) // ordinal doesn't matter for prevouts, only for result outputs
                        prevoutID := addEntry(prevout)
                        // create entry for spend
-                       spend := bytom.NewSpend(&prevoutID, uint64(i))
+                       spend := bc.NewSpend(&prevoutID, uint64(i))
                        spend.WitnessArguments = inp.Arguments
                        spendID := addEntry(spend)
                        // setup mux
-                       muxSources[i] = &bytom.ValueSource{
+                       muxSources[i] = &bc.ValueSource{
                                Ref:   &spendID,
                                Value: &inp.AssetAmount,
                        }
                        spends = append(spends, spend)
 
                case *CoinbaseInput:
-                       coinbase = bytom.NewCoinbase(inp.Arbitrary)
+                       coinbase = bc.NewCoinbase(inp.Arbitrary)
                        coinbaseID := addEntry(coinbase)
 
                        out := tx.Outputs[0]
-                       muxSources[i] = &bytom.ValueSource{
+                       muxSources[i] = &bc.ValueSource{
                                Ref:   &coinbaseID,
                                Value: &out.AssetAmount,
                        }
                }
        }
 
-       mux := bytom.NewMux(muxSources, &bytom.Program{VmVersion: 1, Code: []byte{byte(vm.OP_TRUE)}})
+       mux := bc.NewMux(muxSources, &bc.Program{VmVersion: 1, Code: []byte{byte(vm.OP_TRUE)}})
        muxID := addEntry(mux)
 
        // connect the inputs to the mux
        for _, spend := range spends {
-               spentOutput := entryMap[*spend.SpentOutputId].(*bytom.Output)
+               spentOutput := entryMap[*spend.SpentOutputId].(*bc.Output)
                spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
        }
        for _, issuance := range issuances {
@@ -139,26 +142,26 @@ func mapTx(tx *TxData) (headerID bytom.Hash, hdr *bytom.TxHeader, entryMap map[b
        }
 
        // convert types.outputs to the bytom.output
-       var resultIDs []*bytom.Hash
+       var resultIDs []*bc.Hash
        for i, out := range tx.Outputs {
-               src := &bytom.ValueSource{
+               src := &bc.ValueSource{
                        Ref:      &muxID,
                        Value:    &out.AssetAmount,
                        Position: uint64(i),
                }
-               var resultID bytom.Hash
+               var resultID bc.Hash
                if vmutil.IsUnspendable(out.ControlProgram) {
                        // retirement
-                       r := bytom.NewRetirement(src, uint64(i))
+                       r := bc.NewRetirement(src, uint64(i))
                        resultID = addEntry(r)
                } else {
                        // non-retirement
-                       prog := &bytom.Program{out.VMVersion, out.ControlProgram}
-                       o := bytom.NewOutput(src, prog, uint64(i))
+                       prog := &bc.Program{out.VMVersion, out.ControlProgram}
+                       o := bc.NewOutput(src, prog, uint64(i))
                        resultID = addEntry(o)
                }
 
-               dest := &bytom.ValueDestination{
+               dest := &bc.ValueDestination{
                        Value:    src.Value,
                        Ref:      &resultID,
                        Position: 0,
@@ -167,13 +170,13 @@ func mapTx(tx *TxData) (headerID bytom.Hash, hdr *bytom.TxHeader, entryMap map[b
                mux.WitnessDestinations = append(mux.WitnessDestinations, dest)
        }
 
-       h := bytom.NewTxHeader(tx.Version, tx.SerializedSize, tx.TimeRange, resultIDs)
+       h := bc.NewTxHeader(tx.Version, tx.SerializedSize, tx.TimeRange, resultIDs)
        return addEntry(h), h, entryMap
 }
 
-func mapBlockHeader(old *BlockHeader) (bytom.Hash, *bytom.BlockHeader) {
-       bh := bytom.NewBlockHeader(old.Version, old.Height, &old.PreviousBlockHash, old.Timestamp, &old.TransactionsMerkleRoot, &old.TransactionStatusHash, old.Nonce, old.Bits)
-       return bytom.EntryID(bh), bh
+func mapBlockHeader(old *BlockHeader) (bc.Hash, *bc.BytomBlockHeader) {
+       bh := bc.NewBytomBlockHeader(old.Version, old.Height, &old.PreviousBlockHash, old.Timestamp, &old.TransactionsMerkleRoot, &old.TransactionStatusHash, old.Nonce, old.Bits)
+       return bc.EntryID(bh), bh
 }
 
 // MapBlock converts a types block to bc block
@@ -183,7 +186,7 @@ func MapBlock(old *Block) *bytom.Block {
        }
 
        b := new(bytom.Block)
-       b.ID, b.BlockHeader = mapBlockHeader(&old.BlockHeader)
+       b.ID, b.BytomBlockHeader = mapBlockHeader(&old.BlockHeader)
        for _, oldTx := range old.Transactions {
                b.Transactions = append(b.Transactions, oldTx.Tx)
        }
diff --git a/protocol/bc/types/bytom/types/merkle.go b/protocol/bc/types/bytom/types/merkle.go
deleted file mode 100644 (file)
index d562686..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-package types
-
-import (
-       "container/list"
-       "io"
-       "math"
-
-       "gopkg.in/fatih/set.v0"
-
-       "github.com/vapor/crypto/sha3pool"
-       "github.com/vapor/protocol/bc/types/bytom"
-)
-
-// merkleFlag represent the type of merkle tree node, it's used to generate the structure of merkle tree
-// Bitcoin has only two flags, which zero means the hash of assist node. And one means the hash of the related
-// transaction node or it's parents, which distinguish them according to the height of the tree. But in the bytom,
-// the height of transaction node is not fixed, so we need three flags to distinguish these nodes.
-const (
-       // FlagAssist represent assist node
-       FlagAssist = iota
-       // FlagTxParent represent the parent of transaction of node
-       FlagTxParent
-       // FlagTxLeaf represent transaction of node
-       FlagTxLeaf
-)
-
-var (
-       leafPrefix     = []byte{0x00}
-       interiorPrefix = []byte{0x01}
-)
-
-type merkleNode interface {
-       WriteTo(io.Writer) (int64, error)
-}
-
-func merkleRoot(nodes []merkleNode) (root bytom.Hash, err error) {
-       switch {
-       case len(nodes) == 0:
-               return bytom.EmptyStringHash, nil
-
-       case len(nodes) == 1:
-               root = leafMerkleHash(nodes[0])
-               return root, nil
-
-       default:
-               k := prevPowerOfTwo(len(nodes))
-               left, err := merkleRoot(nodes[:k])
-               if err != nil {
-                       return root, err
-               }
-
-               right, err := merkleRoot(nodes[k:])
-               if err != nil {
-                       return root, err
-               }
-
-               root = interiorMerkleHash(&left, &right)
-               return root, nil
-       }
-}
-
-func interiorMerkleHash(left merkleNode, right merkleNode) (hash bytom.Hash) {
-       h := sha3pool.Get256()
-       defer sha3pool.Put256(h)
-       h.Write(interiorPrefix)
-       left.WriteTo(h)
-       right.WriteTo(h)
-       hash.ReadFrom(h)
-       return hash
-}
-
-func leafMerkleHash(node merkleNode) (hash bytom.Hash) {
-       h := sha3pool.Get256()
-       defer sha3pool.Put256(h)
-       h.Write(leafPrefix)
-       node.WriteTo(h)
-       hash.ReadFrom(h)
-       return hash
-}
-
-type merkleTreeNode struct {
-       hash  bytom.Hash
-       left  *merkleTreeNode
-       right *merkleTreeNode
-}
-
-// buildMerkleTree construct a merkle tree based on the provide node data
-func buildMerkleTree(rawDatas []merkleNode) *merkleTreeNode {
-       switch len(rawDatas) {
-       case 0:
-               return nil
-       case 1:
-               rawData := rawDatas[0]
-               merkleHash := leafMerkleHash(rawData)
-               node := newMerkleTreeNode(merkleHash, nil, nil)
-               return node
-       default:
-               k := prevPowerOfTwo(len(rawDatas))
-               left := buildMerkleTree(rawDatas[:k])
-               right := buildMerkleTree(rawDatas[k:])
-               merkleHash := interiorMerkleHash(&left.hash, &right.hash)
-               node := newMerkleTreeNode(merkleHash, left, right)
-               return node
-       }
-}
-
-func (node *merkleTreeNode) getMerkleTreeProof(merkleHashSet *set.Set) ([]*bytom.Hash, []uint8) {
-       var hashes []*bytom.Hash
-       var flags []uint8
-
-       if node.left == nil && node.right == nil {
-               if key := node.hash.String(); merkleHashSet.Has(key) {
-                       hashes = append(hashes, &node.hash)
-                       flags = append(flags, FlagTxLeaf)
-                       return hashes, flags
-               }
-               return hashes, flags
-       }
-       var leftHashes, rightHashes []*bytom.Hash
-       var leftFlags, rightFlags []uint8
-       if node.left != nil {
-               leftHashes, leftFlags = node.left.getMerkleTreeProof(merkleHashSet)
-       }
-       if node.right != nil {
-               rightHashes, rightFlags = node.right.getMerkleTreeProof(merkleHashSet)
-       }
-       leftFind, rightFind := len(leftHashes) > 0, len(rightHashes) > 0
-
-       if leftFind || rightFind {
-               flags = append(flags, FlagTxParent)
-       } else {
-               return hashes, flags
-       }
-
-       if leftFind {
-               hashes = append(hashes, leftHashes...)
-               flags = append(flags, leftFlags...)
-       } else {
-               hashes = append(hashes, &node.left.hash)
-               flags = append(flags, FlagAssist)
-       }
-
-       if rightFind {
-               hashes = append(hashes, rightHashes...)
-               flags = append(flags, rightFlags...)
-       } else {
-               hashes = append(hashes, &node.right.hash)
-               flags = append(flags, FlagAssist)
-       }
-       return hashes, flags
-}
-
-func getMerkleTreeProof(rawDatas []merkleNode, relatedRawDatas []merkleNode) ([]*bytom.Hash, []uint8) {
-       merkleTree := buildMerkleTree(rawDatas)
-       if merkleTree == nil {
-               return []*bytom.Hash{}, []uint8{}
-       }
-       merkleHashSet := set.New()
-       for _, data := range relatedRawDatas {
-               merkleHash := leafMerkleHash(data)
-               merkleHashSet.Add(merkleHash.String())
-       }
-       if merkleHashSet.Size() == 0 {
-               return []*bytom.Hash{&merkleTree.hash}, []uint8{FlagAssist}
-       }
-       return merkleTree.getMerkleTreeProof(merkleHashSet)
-}
-
-func (node *merkleTreeNode) getMerkleTreeProofByFlags(flagList *list.List) []*bytom.Hash {
-       var hashes []*bytom.Hash
-
-       if flagList.Len() == 0 {
-               return hashes
-       }
-       flagEle := flagList.Front()
-       flag := flagEle.Value.(uint8)
-       flagList.Remove(flagEle)
-
-       if flag == FlagTxLeaf || flag == FlagAssist {
-               hashes = append(hashes, &node.hash)
-               return hashes
-       }
-       if node.left != nil {
-               leftHashes := node.left.getMerkleTreeProofByFlags(flagList)
-               hashes = append(hashes, leftHashes...)
-       }
-       if node.right != nil {
-               rightHashes := node.right.getMerkleTreeProofByFlags(flagList)
-               hashes = append(hashes, rightHashes...)
-       }
-       return hashes
-}
-
-func getMerkleTreeProofByFlags(rawDatas []merkleNode, flagList *list.List) []*bytom.Hash {
-       tree := buildMerkleTree(rawDatas)
-       return tree.getMerkleTreeProofByFlags(flagList)
-}
-
-// GetTxMerkleTreeProof return a proof of merkle tree, which used to proof the transaction does
-// exist in the merkle tree
-func GetTxMerkleTreeProof(txs []*Tx, relatedTxs []*Tx) ([]*bytom.Hash, []uint8) {
-       var rawDatas []merkleNode
-       var relatedRawDatas []merkleNode
-       for _, tx := range txs {
-               rawDatas = append(rawDatas, &tx.ID)
-       }
-       for _, relatedTx := range relatedTxs {
-               relatedRawDatas = append(relatedRawDatas, &relatedTx.ID)
-       }
-       return getMerkleTreeProof(rawDatas, relatedRawDatas)
-}
-
-// GetStatusMerkleTreeProof return a proof of merkle tree, which used to proof the status of transaction is valid
-func GetStatusMerkleTreeProof(statuses []*bytom.TxVerifyResult, flags []uint8) []*bytom.Hash {
-       var rawDatas []merkleNode
-       for _, status := range statuses {
-               rawDatas = append(rawDatas, status)
-       }
-       flagList := list.New()
-       for _, flag := range flags {
-               flagList.PushBack(flag)
-       }
-       return getMerkleTreeProofByFlags(rawDatas, flagList)
-}
-
-// getMerkleRootByProof caculate the merkle root hash according to the proof
-func getMerkleRootByProof(hashList *list.List, flagList *list.List, merkleHashes *list.List) bytom.Hash {
-       if flagList.Len() == 0 || hashList.Len() == 0 {
-               return bytom.EmptyStringHash
-       }
-       flagEle := flagList.Front()
-       flag := flagEle.Value.(uint8)
-       flagList.Remove(flagEle)
-       switch flag {
-       case FlagAssist:
-               {
-                       hash := hashList.Front()
-                       hashList.Remove(hash)
-                       return hash.Value.(bytom.Hash)
-               }
-       case FlagTxLeaf:
-               {
-                       if merkleHashes.Len() == 0 {
-                               return bytom.EmptyStringHash
-                       }
-                       hashEle := hashList.Front()
-                       hash := hashEle.Value.(bytom.Hash)
-                       relatedHashEle := merkleHashes.Front()
-                       relatedHash := relatedHashEle.Value.(bytom.Hash)
-                       if hash == relatedHash {
-                               hashList.Remove(hashEle)
-                               merkleHashes.Remove(relatedHashEle)
-                               return hash
-                       }
-               }
-       case FlagTxParent:
-               {
-                       leftHash := getMerkleRootByProof(hashList, flagList, merkleHashes)
-                       rightHash := getMerkleRootByProof(hashList, flagList, merkleHashes)
-                       hash := interiorMerkleHash(&leftHash, &rightHash)
-                       return hash
-               }
-       }
-       return bytom.EmptyStringHash
-}
-
-func newMerkleTreeNode(merkleHash bytom.Hash, left *merkleTreeNode, right *merkleTreeNode) *merkleTreeNode {
-       return &merkleTreeNode{
-               hash:  merkleHash,
-               left:  left,
-               right: right,
-       }
-}
-
-// ValidateMerkleTreeProof caculate the merkle root according to the hash of node and the flags
-// only if the merkle root by caculated equals to the specify merkle root, and the merkle tree
-// contains all of the related raw datas, the validate result will be true.
-func validateMerkleTreeProof(hashes []*bytom.Hash, flags []uint8, relatedNodes []merkleNode, merkleRoot bytom.Hash) bool {
-       merkleHashes := list.New()
-       for _, relatedNode := range relatedNodes {
-               merkleHashes.PushBack(leafMerkleHash(relatedNode))
-       }
-       hashList := list.New()
-       for _, hash := range hashes {
-               hashList.PushBack(*hash)
-       }
-       flagList := list.New()
-       for _, flag := range flags {
-               flagList.PushBack(flag)
-       }
-       root := getMerkleRootByProof(hashList, flagList, merkleHashes)
-       return root == merkleRoot && merkleHashes.Len() == 0
-}
-
-// ValidateTxMerkleTreeProof validate the merkle tree of transactions
-func ValidateTxMerkleTreeProof(hashes []*bytom.Hash, flags []uint8, relatedHashes []*bytom.Hash, merkleRoot bytom.Hash) bool {
-       var relatedNodes []merkleNode
-       for _, hash := range relatedHashes {
-               relatedNodes = append(relatedNodes, hash)
-       }
-       return validateMerkleTreeProof(hashes, flags, relatedNodes, merkleRoot)
-}
-
-// ValidateStatusMerkleTreeProof validate the merkle tree of transaction status
-func ValidateStatusMerkleTreeProof(hashes []*bytom.Hash, flags []uint8, relatedStatus []*bytom.TxVerifyResult, merkleRoot bytom.Hash) bool {
-       var relatedNodes []merkleNode
-       for _, result := range relatedStatus {
-               relatedNodes = append(relatedNodes, result)
-       }
-       return validateMerkleTreeProof(hashes, flags, relatedNodes, merkleRoot)
-}
-
-// TxStatusMerkleRoot creates a merkle tree from a slice of bytom.TxVerifyResult
-func TxStatusMerkleRoot(tvrs []*bytom.TxVerifyResult) (root bytom.Hash, err error) {
-       nodes := []merkleNode{}
-       for _, tvr := range tvrs {
-               nodes = append(nodes, tvr)
-       }
-       return merkleRoot(nodes)
-}
-
-// TxMerkleRoot creates a merkle tree from a slice of transactions
-// and returns the root hash of the tree.
-func TxMerkleRoot(transactions []*bytom.Tx) (root bytom.Hash, err error) {
-       nodes := []merkleNode{}
-       for _, tx := range transactions {
-               nodes = append(nodes, &tx.ID)
-       }
-       return merkleRoot(nodes)
-}
-
-// prevPowerOfTwo returns the largest power of two that is smaller than a given number.
-// In other words, for some input n, the prevPowerOfTwo k is a power of two such that
-// k < n <= 2k. This is a helper function used during the calculation of a merkle tree.
-func prevPowerOfTwo(n int) int {
-       // If the number is a power of two, divide it by 2 and return.
-       if n&(n-1) == 0 {
-               return n / 2
-       }
-
-       // Otherwise, find the previous PoT.
-       exponent := uint(math.Log2(float64(n)))
-       return 1 << exponent // 2^exponent
-}
index 4665388..e72cf54 100644 (file)
@@ -7,12 +7,12 @@ import (
        "github.com/vapor/crypto/sha3pool"
        "github.com/vapor/encoding/blockchain"
        "github.com/vapor/errors"
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
 )
 
 // OutputCommitment contains the commitment data for a transaction output.
 type OutputCommitment struct {
-       bytom.AssetAmount
+       bc.AssetAmount
        VMVersion      uint64
        ControlProgram []byte
 }
@@ -62,8 +62,8 @@ func (oc *OutputCommitment) readFrom(r *blockchain.Reader, assetVersion uint64)
        })
 }
 
-// Hash convert suffix && assetVersion to bytom.Hash
-func (oc *OutputCommitment) Hash(suffix []byte, assetVersion uint64) (outputhash bytom.Hash) {
+// Hash convert suffix && assetVersion to bc.Hash
+func (oc *OutputCommitment) Hash(suffix []byte, assetVersion uint64) (outputhash bc.Hash) {
        h := sha3pool.Get256()
        defer sha3pool.Put256(h)
        oc.writeExtensibleString(h, suffix, assetVersion)
index 12a7598..8642d35 100644 (file)
@@ -1,7 +1,7 @@
 package types
 
 import (
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
 )
 
 // SpendInput satisfies the TypedInput interface and represents a spend transaction.
@@ -12,9 +12,9 @@ type SpendInput struct {
 }
 
 // NewSpendInput create a new SpendInput struct.
-func NewSpendInput(arguments [][]byte, sourceID bytom.Hash, assetID bytom.AssetID, amount, sourcePos uint64, controlProgram []byte) *TxInput {
+func NewSpendInput(arguments [][]byte, sourceID bc.Hash, assetID bc.AssetID, amount, sourcePos uint64, controlProgram []byte) *TxInput {
        sc := SpendCommitment{
-               AssetAmount: bytom.AssetAmount{
+               AssetAmount: bc.AssetAmount{
                        AssetId: &assetID,
                        Amount:  amount,
                },
index 66b2fb9..1102d58 100644 (file)
@@ -6,13 +6,13 @@ import (
 
        "github.com/vapor/encoding/blockchain"
        "github.com/vapor/errors"
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
 )
 
 // SpendCommitment contains the commitment data for a transaction output.
 type SpendCommitment struct {
-       bytom.AssetAmount
-       SourceID       bytom.Hash
+       bc.AssetAmount
+       SourceID       bc.Hash
        SourcePosition uint64
        VMVersion      uint64
        ControlProgram []byte
index 3953b80..c1aa00b 100644 (file)
@@ -8,6 +8,7 @@ import (
 
        "github.com/vapor/encoding/blockchain"
        "github.com/vapor/errors"
+       "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types/bytom"
 )
 
@@ -29,7 +30,7 @@ func NewTx(data TxData) *Tx {
 }
 
 // OutputID return the hash of the output position
-func (tx *Tx) OutputID(outputIndex int) *bytom.Hash {
+func (tx *Tx) OutputID(outputIndex int) *bc.Hash {
        return tx.ResultIds[outputIndex]
 }
 
@@ -49,9 +50,9 @@ func (tx *Tx) SetInputArguments(n uint32, args [][]byte) {
        id := tx.Tx.InputIDs[n]
        e := tx.Entries[id]
        switch e := e.(type) {
-       case *bytom.Issuance:
+       case *bc.Issuance:
                e.WitnessArguments = args
-       case *bytom.Spend:
+       case *bc.Spend:
                e.WitnessArguments = args
        }
 }
index e7765cd..a44aaf6 100644 (file)
@@ -6,7 +6,8 @@ import (
 
        "github.com/vapor/encoding/blockchain"
        "github.com/vapor/errors"
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
+       "github.com/vapor/protocol/bc/types"
 )
 
 // serflag variables for input types.
@@ -34,36 +35,36 @@ type (
 var errBadAssetID = errors.New("asset ID does not match other issuance parameters")
 
 // AssetAmount return the asset id and amount of the txinput.
-func (t *TxInput) AssetAmount() bytom.AssetAmount {
+func (t *TxInput) AssetAmount() bc.AssetAmount {
        switch inp := t.TypedInput.(type) {
-       case *IssuanceInput:
+       case *types.IssuanceInput:
                assetID := inp.AssetID()
-               return bytom.AssetAmount{
+               return bc.AssetAmount{
                        AssetId: &assetID,
                        Amount:  inp.Amount,
                }
        case *SpendInput:
                return inp.AssetAmount
        }
-       return bytom.AssetAmount{}
+       return bc.AssetAmount{}
 }
 
 // AssetID return the assetID of the txinput
-func (t *TxInput) AssetID() bytom.AssetID {
+func (t *TxInput) AssetID() bc.AssetID {
        switch inp := t.TypedInput.(type) {
-       case *IssuanceInput:
+       case *types.IssuanceInput:
                return inp.AssetID()
        case *SpendInput:
                return *inp.AssetId
 
        }
-       return bytom.AssetID{}
+       return bc.AssetID{}
 }
 
 // Amount return the asset amount of the txinput
 func (t *TxInput) Amount() uint64 {
        switch inp := t.TypedInput.(type) {
-       case *IssuanceInput:
+       case *types.IssuanceInput:
                return inp.Amount
        case *SpendInput:
                return inp.Amount
@@ -81,7 +82,7 @@ func (t *TxInput) ControlProgram() []byte {
 
 // IssuanceProgram return the control program of the issuance input
 func (t *TxInput) IssuanceProgram() []byte {
-       if ii, ok := t.TypedInput.(*IssuanceInput); ok {
+       if ii, ok := t.TypedInput.(*types.IssuanceInput); ok {
                return ii.IssuanceProgram
        }
        return nil
@@ -90,7 +91,7 @@ func (t *TxInput) IssuanceProgram() []byte {
 // Arguments get the args for the input
 func (t *TxInput) Arguments() [][]byte {
        switch inp := t.TypedInput.(type) {
-       case *IssuanceInput:
+       case *types.IssuanceInput:
                return inp.Arguments
        case *SpendInput:
                return inp.Arguments
@@ -101,7 +102,7 @@ func (t *TxInput) Arguments() [][]byte {
 // SetArguments set the args for the input
 func (t *TxInput) SetArguments(args [][]byte) {
        switch inp := t.TypedInput.(type) {
-       case *IssuanceInput:
+       case *types.IssuanceInput:
                inp.Arguments = args
        case *SpendInput:
                inp.Arguments = args
@@ -109,7 +110,7 @@ func (t *TxInput) SetArguments(args [][]byte) {
 }
 
 // SpentOutputID calculate the hash of spended output
-func (t *TxInput) SpentOutputID() (o bytom.Hash, err error) {
+func (t *TxInput) SpentOutputID() (o bc.Hash, err error) {
        if si, ok := t.TypedInput.(*SpendInput); ok {
                o, err = ComputeOutputID(&si.SpendCommitment)
        }
@@ -121,7 +122,7 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                return err
        }
 
-       var assetID bytom.AssetID
+       var assetID bc.AssetID
        t.CommitmentSuffix, err = blockchain.ReadExtensibleString(r, func(r *blockchain.Reader) error {
                if t.AssetVersion != 1 {
                        return nil
@@ -132,7 +133,7 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                }
                switch icType[0] {
                case IssuanceInputType:
-                       ii := new(IssuanceInput)
+                       ii := new(types.IssuanceInput)
                        t.TypedInput = ii
 
                        if ii.Nonce, err = blockchain.ReadVarstr31(r); err != nil {
@@ -174,7 +175,7 @@ func (t *TxInput) readFrom(r *blockchain.Reader) (err error) {
                }
 
                switch inp := t.TypedInput.(type) {
-               case *IssuanceInput:
+               case *types.IssuanceInput:
                        if inp.AssetDefinition, err = blockchain.ReadVarstr31(r); err != nil {
                                return err
                        }
@@ -221,7 +222,7 @@ func (t *TxInput) writeInputCommitment(w io.Writer) (err error) {
        }
 
        switch inp := t.TypedInput.(type) {
-       case *IssuanceInput:
+       case *types.IssuanceInput:
                if _, err = w.Write([]byte{IssuanceInputType}); err != nil {
                        return err
                }
@@ -257,7 +258,7 @@ func (t *TxInput) writeInputWitness(w io.Writer) error {
                return nil
        }
        switch inp := t.TypedInput.(type) {
-       case *IssuanceInput:
+       case *types.IssuanceInput:
                if _, err := blockchain.WriteVarstr31(w, inp.AssetDefinition); err != nil {
                        return err
                }
index 2ac115e..11e1f4a 100644 (file)
@@ -5,7 +5,7 @@ import (
 
        "github.com/vapor/encoding/blockchain"
        "github.com/vapor/errors"
-       "github.com/vapor/protocol/bc/types/bytom"
+       "github.com/vapor/protocol/bc"
 )
 
 // TxOutput is the top level struct of tx output.
@@ -17,11 +17,11 @@ type TxOutput struct {
 }
 
 // NewTxOutput create a new output struct
-func NewTxOutput(assetID bytom.AssetID, amount uint64, controlProgram []byte) *TxOutput {
+func NewTxOutput(assetID bc.AssetID, amount uint64, controlProgram []byte) *TxOutput {
        return &TxOutput{
                AssetVersion: 1,
                OutputCommitment: OutputCommitment{
-                       AssetAmount: bytom.AssetAmount{
+                       AssetAmount: bc.AssetAmount{
                                AssetId: &assetID,
                                Amount:  amount,
                        },
@@ -66,19 +66,19 @@ func (to *TxOutput) writeCommitment(w io.Writer) error {
 
 // ComputeOutputID assembles an output entry given a spend commitment and
 // computes and returns its corresponding entry ID.
-func ComputeOutputID(sc *SpendCommitment) (h bytom.Hash, err error) {
+func ComputeOutputID(sc *SpendCommitment) (h bc.Hash, err error) {
        defer func() {
                if r, ok := recover().(error); ok {
                        err = r
                }
        }()
-       src := &bytom.ValueSource{
+       src := &bc.ValueSource{
                Ref:      &sc.SourceID,
                Value:    &sc.AssetAmount,
                Position: sc.SourcePosition,
        }
-       o := bytom.NewOutput(src, &bytom.Program{VmVersion: sc.VMVersion, Code: sc.ControlProgram}, 0)
+       o := bc.NewOutput(src, &bc.Program{VmVersion: sc.VMVersion, Code: sc.ControlProgram}, 0)
 
-       h = bytom.EntryID(o)
+       h = bc.EntryID(o)
        return h, nil
 }
index cf5598f..8ed6d7a 100644 (file)
@@ -29,6 +29,12 @@ func (c *Chain) ValidateTx(tx *types.Tx) (bool, error) {
        if ok := c.txPool.HaveTransaction(&tx.ID); ok {
                return false, c.txPool.GetErrCache(&tx.ID)
        }
+
+       if ok := c.txPool.IsWithdrawSpent(tx); ok {
+               log.WithFields(log.Fields{"module": "ValidateTx", "error": "Cliam transactions already exist in the trading pool"}).Error("chain error")
+               return false, errors.New("Cliam transactions already exist in the trading pool")
+       }
+
        bh := c.BestBlockHeader()
        block := types.MapBlock(&types.Block{BlockHeader: *bh})
        gasStatus, err := validation.ValidateTx(tx.Tx, block)
index 1eb2fa0..0511171 100644 (file)
@@ -66,6 +66,7 @@ type TxPool struct {
        utxo          map[bc.Hash]*types.Tx
        orphans       map[bc.Hash]*orphanTx
        orphansByPrev map[bc.Hash]map[bc.Hash]*orphanTx
+       claimTx       map[bc.Hash]bool
        errCache      *lru.Cache
        msgCh         chan *TxPoolMsg
 }
@@ -79,6 +80,7 @@ func NewTxPool(store Store) *TxPool {
                utxo:          make(map[bc.Hash]*types.Tx),
                orphans:       make(map[bc.Hash]*orphanTx),
                orphansByPrev: make(map[bc.Hash]map[bc.Hash]*orphanTx),
+               claimTx:       make(map[bc.Hash]bool),
                errCache:      lru.New(maxCachedErrTxs),
                msgCh:         make(chan *TxPoolMsg, maxMsgChSize),
        }
@@ -136,6 +138,7 @@ func (tp *TxPool) RemoveTransaction(txHash *bc.Hash) {
        for _, output := range txD.Tx.ResultIds {
                delete(tp.utxo, *output)
        }
+       tp.removeClaimTx(txD.Tx)
        delete(tp.pool, *txHash)
 
        atomic.StoreInt64(&tp.lastUpdated, time.Now().Unix())
@@ -196,7 +199,8 @@ func (tp *TxPool) ProcessTransaction(tx *types.Tx, statusFail bool, height, fee
        tp.mtx.Lock()
        defer tp.mtx.Unlock()
 
-       if tp.isWithdrawSpent(tx) {
+       if tp.IsWithdrawSpent(tx) {
+               log.WithFields(log.Fields{"module": "ProcessTransaction", "error": "pegin-already-claimed"}).Error("ProcessTransaction error")
                return false, errors.New("pegin-already-claimed")
        }
 
@@ -223,11 +227,12 @@ func (tp *TxPool) ProcessTransaction(tx *types.Tx, statusFail bool, height, fee
        return false, nil
 }
 
-func (tp *TxPool) isWithdrawSpent(tx *types.Tx) bool {
+func (tp *TxPool) IsWithdrawSpent(tx *types.Tx) bool {
        for key, value := range tx.Entries {
                switch value.(type) {
                case *bc.Claim:
-                       return tp.store.IsWithdrawSpent(&key)
+                       _, ok := tp.claimTx[key]
+                       return tp.store.IsWithdrawSpent(&key) || ok
                default:
                        continue
                }
@@ -236,6 +241,28 @@ func (tp *TxPool) isWithdrawSpent(tx *types.Tx) bool {
        return false
 }
 
+func (tp *TxPool) addClaimTx(tx *types.Tx) {
+       for key, value := range tx.Entries {
+               switch value.(type) {
+               case *bc.Claim:
+                       tp.claimTx[key] = true
+               default:
+                       continue
+               }
+       }
+}
+
+func (tp *TxPool) removeClaimTx(tx *types.Tx) {
+       for key, value := range tx.Entries {
+               switch value.(type) {
+               case *bc.Claim:
+                       delete(tp.claimTx, key)
+               default:
+                       continue
+               }
+       }
+}
+
 func (tp *TxPool) addOrphan(txD *TxDesc, requireParents []*bc.Hash) error {
        if len(tp.orphans) >= maxOrphanNum {
                return ErrPoolIsFull
@@ -260,6 +287,8 @@ func (tp *TxPool) addTransaction(txD *TxDesc) error {
        tx := txD.Tx
        txD.Added = time.Now()
        tp.pool[tx.ID] = txD
+       // 增加一个claim id 到到claim pool中
+       tp.addClaimTx(tx)
        for _, id := range tx.ResultIds {
                output, err := tx.Output(*id)
                if err != nil {
index abdd0a0..421cc8a 100644 (file)
@@ -10,10 +10,12 @@ import (
        "github.com/vapor/consensus"
        "github.com/vapor/consensus/segwit"
        "github.com/vapor/crypto"
+       "github.com/vapor/equity/pegin_contract"
        "github.com/vapor/errors"
        "github.com/vapor/math/checked"
        "github.com/vapor/protocol/bc"
        "github.com/vapor/protocol/bc/types"
+       bytomtypes "github.com/vapor/protocol/bc/types/bytom/types"
        "github.com/vapor/protocol/vm"
        "github.com/vapor/protocol/vm/vmutil"
        "github.com/vapor/util"
@@ -324,11 +326,11 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
                        return errors.New("pegin-no-witness")
                }
 
-               if IsValidPeginWitness(stack, *spentOutput) == nil {
-                       return errors.New("PeginWitness invalid")
+               if err := IsValidPeginWitness(stack, *spentOutput); err != nil {
+                       return err
                }
 
-               // 判断cliamd的输入是否已经被用
+               // 判断cliam tx的输入是否已经被用
 
                eq, err := spentOutput.Source.Value.Equal(e.WitnessDestination.Value)
                if err != nil {
@@ -359,14 +361,42 @@ func checkValid(vs *validationState, e bc.Entry) (err error) {
 }
 
 type MerkleBlock struct {
-       BlockHeader  types.BlockHeader `json:"block_header"`
-       TxHashes     []*bc.Hash        `json:"tx_hashes"`
-       StatusHashes []*bc.Hash        `json:"status_hashes"`
-       Flags        []uint32          `json:"flags"`
-       MatchedTxIDs []*bc.Hash        `json:"matched_tx_ids"`
+       BlockHeader  []byte     `json:"block_header"`
+       TxHashes     []*bc.Hash `json:"tx_hashes"`
+       StatusHashes []*bc.Hash `json:"status_hashes"`
+       Flags        []uint32   `json:"flags"`
+       MatchedTxIDs []*bc.Hash `json:"matched_tx_ids"`
 }
 
 func IsValidPeginWitness(peginWitness [][]byte, prevout bc.Output) (err error) {
+       /*
+               assetID := bc.AssetID{}
+               assetID.V0 = prevout.Source.Value.AssetId.GetV0()
+               assetID.V1 = prevout.Source.Value.AssetId.GetV1()
+               assetID.V2 = prevout.Source.Value.AssetId.GetV2()
+               assetID.V3 = prevout.Source.Value.AssetId.GetV3()
+               //bytomPrevout.Source.Value.AssetId = &assetId
+
+               sourceID := bc.Hash{}
+               sourceID.V0 = prevout.Source.Ref.GetV0()
+               sourceID.V1 = prevout.Source.Ref.GetV1()
+               sourceID.V2 = prevout.Source.Ref.GetV2()
+               sourceID.V3 = prevout.Source.Ref.GetV3()
+       */
+
+       assetAmount := &bc.AssetAmount{
+               AssetId: prevout.Source.Value.AssetId,
+               Amount:  prevout.Source.Value.Amount,
+       }
+
+       src := &bc.ValueSource{
+               Ref:      prevout.Source.Ref,
+               Value:    assetAmount,
+               Position: prevout.Source.Position,
+       }
+       prog := &bc.Program{prevout.ControlProgram.VmVersion, prevout.ControlProgram.Code}
+       bytomPrevout := bc.NewOutput(src, prog, prevout.Source.Position)
+
        if len(peginWitness) != 5 {
                return errors.New("peginWitness is error")
        }
@@ -374,23 +404,24 @@ func IsValidPeginWitness(peginWitness [][]byte, prevout bc.Output) (err error) {
        if err != nil {
                return err
        }
-       if consensus.MoneyRange(amount) {
+       if !consensus.MoneyRange(amount) {
                return errors.New("Amount out of range")
        }
 
-       if len(peginWitness[1]) != 32 {
+       if len(peginWitness[1]) != 64 {
                return errors.New("The length of gennesisBlockHash is not correct")
        }
 
        claimScript := peginWitness[2]
 
-       var rawTx types.Tx
-       err = json.Unmarshal(peginWitness[3], &rawTx)
+       rawTx := &bytomtypes.Tx{}
+       err = rawTx.UnmarshalText(peginWitness[3])
        if err != nil {
                return err
        }
-       var merkleBlock MerkleBlock
-       err = json.Unmarshal(peginWitness[4], &merkleBlock)
+
+       merkleBlock := &MerkleBlock{}
+       err = json.Unmarshal(peginWitness[4], merkleBlock)
        if err != nil {
                return err
        }
@@ -399,19 +430,20 @@ func IsValidPeginWitness(peginWitness [][]byte, prevout bc.Output) (err error) {
        for flag := range merkleBlock.Flags {
                flags = append(flags, uint8(flag))
        }
-       if !types.ValidateTxMerkleTreeProof(merkleBlock.TxHashes, flags, merkleBlock.MatchedTxIDs, merkleBlock.BlockHeader.BlockCommitment.TransactionsMerkleRoot) {
+       blockHeader := &bytomtypes.BlockHeader{}
+       if err = blockHeader.UnmarshalText(merkleBlock.BlockHeader); err != nil {
+               return err
+       }
+
+       if !types.ValidateTxMerkleTreeProof(merkleBlock.TxHashes, flags, merkleBlock.MatchedTxIDs, blockHeader.BlockCommitment.TransactionsMerkleRoot) {
                return errors.New("Merkleblock validation failed")
        }
-       var txHash bc.Hash = rawTx.ID
+
        // 交易进行验证
-       if !checkPeginTx(&rawTx, &prevout, amount, claimScript) {
-               return errors.New("check PeginTx fail")
+       if err = checkPeginTx(rawTx, bytomPrevout, amount, claimScript); err != nil {
+               return err
        }
 
-       // Check that the merkle proof corresponds to the txid
-       if txHash != *prevout.Source.Ref {
-               return errors.New("prevout hash don't match")
-       }
        // Check the genesis block corresponds to a valid peg (only one for now)
        if !bytes.Equal(peginWitness[1], []byte(consensus.ActiveNetParams.ParentGenesisBlockHash)) {
                return errors.New("ParentGenesisBlockHash don't match")
@@ -419,7 +451,7 @@ func IsValidPeginWitness(peginWitness [][]byte, prevout bc.Output) (err error) {
        // TODO Finally, validate peg-in via rpc call
 
        if util.ValidatePegin {
-               if err := util.IsConfirmedBytomBlock(merkleBlock.BlockHeader.Height, consensus.ActiveNetParams.PeginMinDepth); err != nil {
+               if err := util.IsConfirmedBytomBlock(blockHeader.Height, consensus.ActiveNetParams.PeginMinDepth); err != nil {
                        return err
                }
        }
@@ -427,27 +459,29 @@ func IsValidPeginWitness(peginWitness [][]byte, prevout bc.Output) (err error) {
        return nil
 }
 
-func checkPeginTx(rawTx *types.Tx, prevout *bc.Output, claimAmount uint64, claimScript []byte) bool {
-       // Check that transaction matches txid
-       if rawTx.ID != *prevout.Source.Ref {
-               return false
-       }
+func checkPeginTx(rawTx *bytomtypes.Tx, prevout *bc.Output, claimAmount uint64, claimScript []byte) error {
        // Check the transaction nout/value matches
        amount := rawTx.Outputs[prevout.Source.Position].Amount
        if claimAmount != amount {
-               return false
+               return errors.New("transaction nout/value do not matches")
        }
        // Check that the witness program matches the p2ch on the p2sh-p2wsh transaction output
-       federationRedeemScript := vmutil.CalculateContract(consensus.ActiveNetParams.FedpegXPubs, claimScript)
-       scriptHash := crypto.Sha256(federationRedeemScript)
+       //federationRedeemScript := vmutil.CalculateContract(consensus.ActiveNetParams.FedpegXPubs, claimScript)
+       //scriptHash := crypto.Sha256(federationRedeemScript)
+       peginContractPrograms, err := pegin_contract.GetPeginContractPrograms(claimScript)
+       if err != nil {
+               return err
+       }
+
+       scriptHash := crypto.Sha256(peginContractPrograms)
        controlProg, err := vmutil.P2WSHProgram(scriptHash)
        if err != nil {
-               return false
+               return err
        }
-       if bytes.Equal(rawTx.Outputs[prevout.Source.Position].ControlProgram, controlProg) {
-               return false
+       if !bytes.Equal(rawTx.Outputs[prevout.Source.Position].ControlProgram, controlProg) {
+               return errors.New("The output control program of transaction does not match the control program of the system's alliance contract")
        }
-       return true
+       return nil
 }
 
 func checkValidSrc(vstate *validationState, vs *bc.ValueSource) error {
diff --git a/tools/monitor_tx/http_client.go b/tools/monitor_tx/http_client.go
new file mode 100644 (file)
index 0000000..edb8336
--- /dev/null
@@ -0,0 +1,50 @@
+package main
+
+import (
+       "encoding/json"
+       "errors"
+       "io/ioutil"
+       "net/http"
+)
+
+type RespMsg struct {
+       MainchainAddress string `json:"mainchain_address,omitempty"`
+       ControlProgram   string `json:"control_program,omitempty"`
+       ClaimScript      string `json:"claim_script,omitempty"`
+}
+
+type Response struct {
+       Code int    `json:"code,omitempty"`
+       Msg  string `json:"msg,omitempty"`
+       Data string `json:"data,omitempty"`
+}
+
+func getPeginInfo() (map[string]string, error) {
+       resp, err := http.Get("http://127.0.0.1:8000/api/get_pegin_address")
+       if err != nil {
+               return nil, err
+       }
+       if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+               return nil, errors.New("connect fail")
+       }
+       body, err := ioutil.ReadAll(resp.Body)
+       if err != nil {
+               return nil, err
+       }
+
+       rep := Response{}
+       err = json.Unmarshal(body, &rep)
+       if err != nil {
+               return nil, err
+       }
+       var msg []RespMsg
+       err = json.Unmarshal([]byte(rep.Data), &msg)
+       if err != nil {
+               return nil, err
+       }
+       mapMsg := make(map[string]string)
+       for _, m := range msg {
+               mapMsg[m.ClaimScript] = m.ControlProgram
+       }
+       return mapMsg, nil
+}
diff --git a/tools/monitor_tx/main.go b/tools/monitor_tx/main.go
new file mode 100644 (file)
index 0000000..2e84800
--- /dev/null
@@ -0,0 +1,287 @@
+package main
+
+import (
+       "bytes"
+       "encoding/json"
+       "fmt"
+       "log"
+       "os"
+       "sync"
+       "time"
+
+       "github.com/spf13/cobra"
+       "github.com/vapor/config"
+       chainjson "github.com/vapor/encoding/json"
+       bytomtypes "github.com/vapor/protocol/bc/types/bytom/types"
+       "github.com/vapor/util"
+)
+
+var lock sync.Mutex
+var gClaimTxMap map[uint64]claimTx
+var currentHeight uint64
+
+type WSRequest struct {
+       Topic string `json:"topic"`
+}
+
+type WSResponse struct {
+       NotificationType string      `json:"notification_type"`
+       Data             interface{} `json:"data"`
+       ErrorDetail      string      `json:"error_detail,omitempty"`
+}
+
+type claimTx struct {
+       Password     string                 `json:"password"`
+       RawTx        bytomtypes.Tx          `json:"raw_transaction"`
+       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
+       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
+       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
+       Flags        []uint32               `json:"flags"`
+       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
+       ClaimScript  chainjson.HexBytes     `json:"claim_script"`
+}
+
+var startHeight uint64 = 0
+
+var runCmd = &cobra.Command{
+       Use:   "run",
+       Short: "monitor claim tx",
+       Run:   run,
+}
+
+func init() {
+       runCmd.PersistentFlags().Uint64Var(&startHeight, "start_height", 0, "Start monitoring block height for transactions")
+}
+
+func run(cmd *cobra.Command, args []string) {
+
+}
+
+func main() {
+
+       if _, err := runCmd.ExecuteC(); err != nil {
+               os.Exit(util.ErrLocalExe)
+       }
+
+       gClaimTxMap = make(map[uint64]claimTx)
+       currentHeight = 0
+       client := &WSClient{}
+       if err := client.New("127.0.0.1:9888"); err != nil {
+               log.Println(err)
+               return
+       }
+       go sendClaimTx()
+       go getRawTransactionWithHeight()
+       req := WSRequest{
+               Topic: "notify_raw_blocks",
+       }
+       client.SendData(req)
+
+       for {
+               msg, err := client.RecvData()
+               if err != nil {
+                       fmt.Println(err)
+                       break
+               }
+               var rep WSResponse
+               err = json.Unmarshal(msg, &rep)
+               if err != nil {
+                       log.Printf("Unmarshal error:", err)
+               }
+
+               block := &bytomtypes.Block{}
+               switch rep.NotificationType {
+               case "raw_blocks_connected":
+                       data := fmt.Sprint(rep.Data)
+                       err = block.UnmarshalText([]byte(data))
+                       if err != nil {
+                               block = nil
+                       }
+               case "raw_blocks_disconnected":
+                       data := fmt.Sprint(rep.Data)
+                       err = block.UnmarshalText([]byte(data))
+                       if err != nil {
+                               block = nil
+                       }
+               case "request_status":
+                       if rep.ErrorDetail != "" {
+                               log.Println(rep.ErrorDetail)
+                       }
+                       block = nil
+               default:
+                       block = nil
+               }
+               if block != nil {
+                       currentHeight = block.Height
+                       err := getRawTransaction(block)
+                       if err != nil {
+                               log.Fatal(err)
+                       }
+               }
+       }
+}
+
+func sendClaimTx() {
+       for {
+               // 存储tx到数据库、列表中
+               for k, v := range gClaimTxMap {
+                       if k <= currentHeight {
+                               resp, exitCode := util.ClientCall("/claim-pegin-transaction", &v)
+                               if exitCode != util.Success {
+                                       lock.Lock()
+                                       delete(gClaimTxMap, k)
+                                       lock.Unlock()
+                                       continue
+                               }
+                               type txID struct {
+                                       Txid string `json:"tx_id"`
+                               }
+                               var out txID
+                               restoreStruct(resp, &out)
+                               lock.Lock()
+                               delete(gClaimTxMap, k)
+                               lock.Unlock()
+                               fmt.Println(out.Txid)
+                               time.Sleep(3 * time.Second)
+                       }
+               }
+       }
+
+}
+
+func restoreStruct(data interface{}, out interface{}) {
+       dataMap, ok := data.(map[string]interface{})
+       if ok != true {
+               fmt.Println("invalid type assertion")
+               os.Exit(util.ErrLocalParse)
+       }
+
+       rawData, err := json.MarshalIndent(dataMap, "", "  ")
+       if err != nil {
+               fmt.Println(err)
+               os.Exit(util.ErrLocalParse)
+       }
+       json.Unmarshal(rawData, out)
+}
+
+func getRawTransaction(block *bytomtypes.Block) error {
+       peginInfo, err := getPeginInfo()
+       if err != nil {
+               return err
+       }
+       for _, tx := range block.Transactions {
+               for _, output := range tx.Outputs {
+                       for k, v := range peginInfo {
+                               var claimScript chainjson.HexBytes
+                               if err := claimScript.UnmarshalText([]byte(k)); err != nil {
+                                       return err
+                               }
+                               var controlProgram chainjson.HexBytes
+                               if err := controlProgram.UnmarshalText([]byte(v)); err != nil {
+                                       return err
+                               }
+
+                               if !bytes.Equal(output.ControlProgram, controlProgram) {
+                                       continue
+                               }
+                               blockHash := block.Hash()
+                               merkleProof, err := getMerkleProof(blockHash.String(), tx.ID.String())
+                               if err != nil {
+                                       return err
+                               }
+                               tmp := claimTx{
+                                       Password:     "123456",
+                                       RawTx:        *tx,
+                                       BlockHeader:  merkleProof.BlockHeader,
+                                       TxHashes:     merkleProof.TxHashes,
+                                       StatusHashes: merkleProof.StatusHashes,
+                                       Flags:        merkleProof.Flags,
+                                       MatchedTxIDs: merkleProof.MatchedTxIDs,
+                                       ClaimScript:  claimScript,
+                               }
+                               // 存储tx到数据库、列表中
+                               height := block.Height + 6
+                               lock.Lock()
+                               gClaimTxMap[height] = tmp
+                               lock.Unlock()
+                       }
+               }
+       }
+
+       return nil
+}
+
+func getRawTransactionWithHeight() {
+       for {
+               if currentHeight > 0 {
+                       num := currentHeight - startHeight
+                       for i := uint64(0); i < num; i++ {
+                               block, err := getBlockWithHeight(startHeight)
+                               if err != nil {
+                                       log.Fatal(err)
+                               }
+                               err = getRawTransaction(&block)
+                               if err != nil {
+                                       log.Fatal(err)
+                               }
+                               startHeight += 1
+                       }
+                       if startHeight >= currentHeight {
+                               break
+                       }
+               }
+               time.Sleep(1 * time.Second)
+       }
+}
+
+type MerkleBlockResp struct {
+       BlockHeader  bytomtypes.BlockHeader `json:"block_header"`
+       TxHashes     []chainjson.HexBytes   `json:"tx_hashes"`
+       StatusHashes []chainjson.HexBytes   `json:"status_hashes"`
+       Flags        []uint32               `json:"flags"`
+       MatchedTxIDs []chainjson.HexBytes   `json:"matched_tx_ids"`
+}
+
+func getMerkleProof(blockHash string, txId string) (MerkleBlockResp, error) {
+       //body_json = {"tx_id": tx_id,"block_hash": block_hash}
+       type Req struct {
+               TxID      string `json:"tx_id"`
+               BlockHash string `json:"block_hash"`
+       }
+       util.MainchainConfig = &config.MainChainRpcConfig{
+               MainchainRpcHost: "127.0.0.1",
+               MainchainRpcPort: "9888",
+       }
+       var blockHeader MerkleBlockResp
+       resp, err := util.CallRPC("/get-merkle-proof", &Req{TxID: txId, BlockHash: blockHash})
+       if err != nil {
+               return blockHeader, err
+       }
+       tmp, _ := json.Marshal(resp)
+
+       json.Unmarshal(tmp, &blockHeader)
+
+       return blockHeader, nil
+}
+
+func getBlockWithHeight(blockHeight uint64) (bytomtypes.Block, error) {
+       type Req struct {
+               BlockHeight uint64 `json:"block_height"`
+       }
+       util.MainchainConfig = &config.MainChainRpcConfig{
+               MainchainRpcHost: "127.0.0.1",
+               MainchainRpcPort: "9888",
+       }
+       type RawBlockResp struct {
+               RawBlock *bytomtypes.Block `json:"raw_block"`
+       }
+       var block RawBlockResp
+       resp, err := util.CallRPC("/get-raw-block", &Req{BlockHeight: blockHeight})
+       if err != nil {
+               return *block.RawBlock, err
+       }
+       tmp, _ := json.Marshal(resp)
+
+       json.Unmarshal(tmp, &block)
+       return *block.RawBlock, nil
+}
diff --git a/tools/monitor_tx/ws_client.go b/tools/monitor_tx/ws_client.go
new file mode 100644 (file)
index 0000000..e454562
--- /dev/null
@@ -0,0 +1,32 @@
+package main
+
+import (
+       "encoding/json"
+       "net/url"
+
+       "github.com/gorilla/websocket"
+)
+
+type WSClient struct {
+       Conn *websocket.Conn
+}
+
+func (WS *WSClient) New(host string) error {
+       u := url.URL{Scheme: "ws", Host: host, Path: "/websocket-subscribe"}
+       c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
+       if err != nil {
+               return err
+       }
+       WS.Conn = c
+       return nil
+}
+
+func (WS *WSClient) SendData(req interface{}) {
+       msg, _ := json.Marshal(req)
+       WS.Conn.WriteMessage(websocket.TextMessage, msg)
+}
+
+func (WS *WSClient) RecvData() ([]byte, error) {
+       _, msg, err := WS.Conn.ReadMessage()
+       return msg, err
+}
index 1e703f6..88972ba 100644 (file)
@@ -1,5 +1,6 @@
 import requests
 import json
+from websocket import create_connection
 
 
 class Connection(object):
@@ -16,3 +17,17 @@ class Connection(object):
     @staticmethod
     def generate():
         return Connection("http://127.0.0.1:9888")
+
+
+class WSClient(object):
+    def __init__(self, url):
+        self.ws = create_connection(url)
+
+    def send(self, data):
+        self.ws.send(data)
+    
+    def recv(self):
+        return self.ws.recv()
+    
+    def close(self):
+        self.ws.close()
index aa540e4..3788508 100644 (file)
@@ -4,7 +4,7 @@ from flask import request, jsonify, make_response, current_app, render_template
 #from sqlalchemy.exc import SQLAlchemyError, IntegrityError
 
 from . import api
-from .Connection import Connection
+from .Connection import Connection, WSClient
 from .. import db
 from ..models import KeyPair, PeginAddress
 
@@ -56,12 +56,13 @@ def create_pegin_address():
     accountID = request.json['account_id']
     connSide = Connection("http://127.0.0.1:8888")
     body_json = {"account_id": accountID}
-    response = connSide.request("/get-pegin-address",body_json)
+    response = connSide.request("/get-pegin-contract-address",body_json)
     resp_json = json.loads(response.text)
     if resp_json['status'] == 'success':
         mainchain_address = resp_json['data']['mainchain_address']
+        control_program = resp_json['data']['control_program']
         claim_script = resp_json['data']['claim_script']
-        pegin = PeginAddress(address=mainchain_address, claim_script=claim_script)
+        pegin = PeginAddress(address=mainchain_address, control_program=control_program, claim_script=claim_script)
         db.session.add(pegin)
         db.session.commit()
     elif resp_json['status'] == 'fail':
@@ -80,6 +81,7 @@ def get_pegin_address():
     for peginAddr in peginAddrs:
         data = {
             "mainchain_address":peginAddr.address.encode('utf-8'),
+            "control_program":peginAddr.control_program.encode('utf-8'),
             "claim_script": peginAddr.claim_script.encode('utf-8')
         }
         json_data = json_data + json.dumps(data)
@@ -91,7 +93,6 @@ def get_pegin_address():
 
 @api.route('/claim_tx', methods=['GET', 'POST', 'OPTIONS'])
 def claim_tx():
-    print request.json
     if not request.json or not 'claim_script' in request.json or not 'block_height' in request.json or not 'tx_id' in request.json or not 'password' in request.json:
         return json_contents(jsonify(code=-1, msg="The json format is incorrect"))
     block_height = int(request.json['block_height'])
@@ -111,7 +112,8 @@ def claim_tx():
     if resp_json['status'] == 'success':
         raw_block = resp_json['data']['raw_block'].encode('utf-8')
     elif resp_json['status'] == 'fail':
-        return json_contents(jsonify(code=-1, msg="get-raw-block: " + resp_json['msg']))
+        print resp_json
+        return json_contents(jsonify(code=-1, msg="get-raw-block: " + resp_json['error_detail']))
     else:
         return json_contents(jsonify(code=-1, msg="get raw block fail"))
 
@@ -123,18 +125,21 @@ def claim_tx():
         raw_transaction = resp_json['data']['raw_transaction'].encode('utf-8')
         block_hash = resp_json['data']['block_hash'].encode('utf-8')
     elif resp_json['status'] == 'fail':
-        return json_contents(jsonify(code=-1, msg="get-raw-transaction: " + resp_json['msg']))
+        print resp_json
+        return json_contents(jsonify(code=-1, msg="get-raw-transaction: " + resp_json['error_detail']))
     else:
         return json_contents(jsonify(code=-1, msg="get raw transaction fail"))
 
     # 主链获取proof
+    print block_hash
     body_json = {"tx_id": tx_id,"block_hash": block_hash}
     response = connMain.request("/get-merkle-proof",body_json)
     resp_json = json.loads(response.text)
     if resp_json['status'] == 'success':
         proof = json.dumps(resp_json['data']).strip('{}')
     elif resp_json['status'] == 'fail':
-        return json_contents(jsonify(code=-1, msg="get-merkle-proof:" + resp_json['msg']))
+        print resp_json
+        return json_contents(jsonify(code=-1, msg="get-merkle-proof:" + resp_json['error_detail']))
     else:
         return json_contents(jsonify(code=-1, msg="get raw transaction fail"))
 
@@ -146,7 +151,8 @@ def claim_tx():
     if resp_json['status'] == 'success':
         return json_contents(jsonify(code=200, msg=resp_json['data']))
     elif resp_json['status'] == 'fail':
-        return json_contents(jsonify(code=-1, msg="claim-pegin-transaction: " + resp_json['msg']))
+        print resp_json
+        return json_contents(jsonify(code=-1, msg="claim-pegin-transaction: " + resp_json['error_detail']))
     else:
         return json_contents(jsonify(code=-1, msg="claim pegin transaction fail"))
 
@@ -223,8 +229,7 @@ def send_to_mainchain():
         return json_contents(jsonify(code=-1, msg="get side raw transaction fail"))
 
     # 构建主链交易
-    body_json = '{"claim_script":"%s","raw_transaction": "%s","alias": "%s","control_program":"%s","root_xpubs":%s,%s}' % (claim_script,raw_transaction,alias,control_program,root_xpubs,utxo)
-    print body_json
+    body_json = '{"claim_script":"%s","raw_transaction": "%s","control_program":"%s","root_xpubs":%s,%s}' % (claim_script,raw_transaction,control_program,root_xpubs,utxo)
     response = connSide.request("/build-mainchain-tx",json.loads(body_json))
     resp_json = json.loads(response.text.encode('utf-8'))
     tmpl = ""
@@ -237,15 +242,12 @@ def send_to_mainchain():
         return json_contents(jsonify(code=-1, msg="build mainchain transaction fail"))
 
     # 签名
-    #xpubs = request.json['root_xpubs']
-    #xprvs = request.json['xprvs']
-    #for index in range(len(xpubs)):
     for key,value in key_pair.items():
-        #xprv = request.json['xprv'].encode('utf-8')
         body_json = '{"xprv": "%s","xpub":"%s","transaction":%s,"claim_script":"%s"}' % (key,value,tmpl,claim_script)
         response = connSide.request("/sign-with-key",json.loads(body_json))
         resp_json = json.loads(response.text.encode('utf-8'))
         if resp_json['status'] == 'success':
+            tmpl = json.dumps(resp_json['data']['transaction'])
             raw_transaction = resp_json['data']['transaction']['raw_transaction'].encode('utf-8')
         elif resp_json['status'] == 'fail':
             return json_contents(jsonify(code=-1, msg="sign-with-key: " + resp_json['msg']))
@@ -256,6 +258,7 @@ def send_to_mainchain():
     body_json = '{"raw_transaction": "%s"}' % (raw_transaction)
     response = connMain.request("/submit-transaction",json.loads(body_json))
     resp_json = json.loads(response.text.encode('utf-8'))
+    print resp_json
     if resp_json['status'] == 'success':
         return json_contents(jsonify(code=200, msg=resp_json['data']))
     elif resp_json['status'] == 'fail':
index de5951c..531c765 100644 (file)
@@ -13,6 +13,7 @@ class PeginAddress(db.Model):
     __tablename__ = 'pegin_address'
     id = db.Column(db.Integer, primary_key=True)
     address = db.Column(db.String, nullable=True, unique=True)
+    control_program = db.Column(db.String, nullable=True, unique=True)
     claim_script = db.Column(db.String, nullable=True, unique=True)
 
 class TxInfo(db.Model):
@@ -20,4 +21,4 @@ class TxInfo(db.Model):
     id = db.Column(db.Integer, primary_key=True)
     block_height = db.Column(db.Integer, nullable=True, unique=True)
     txid_main = db.Column(db.String, nullable=True, unique=True)
-    txid_claim = db.Column(db.String, nullable=True, unique=True)
\ No newline at end of file
+    txid_claim = db.Column(db.String, nullable=True, unique=True)
index 0865470..1000998 100644 (file)
@@ -4,7 +4,7 @@ if [ ! -f "key_pair" ];then
 ./vapor init --chain_id solonet -r "side_chain"
 nohup ./vapor node -r "side_chain" > /dev/null &
 sleep 30
-curl -s -X POST -d '{}' http://127.0.0.1:8888/create-key-pair > key_pair
+curl -s -X POST -d '{}' http://127.0.0.1:8888/create-key-pair >> key_pair
 ps -ef | grep vapor | grep -v grep | awk  '{print $2}' |xargs  kill -9
 rm -rf side_chain
 fi
@@ -31,7 +31,7 @@ python manager.py db upgrade
 touch install
 fi
 
-nohup python manager.py runserver -p 8080 -h 0.0.0.0 > /dev/null &
+nohup python manager.py runserver -p 8000 -h 0.0.0.0 > /dev/null &
 sleep 30
 cd web
-nohup python -m SimpleHTTPServer 80 > /dev/null &
+nohup python -m SimpleHTTPServer 8080 > /dev/null &