4 "github.com/vapor/protocol/bc/types/bytom"
5 "github.com/vapor/protocol/vm"
6 "github.com/vapor/protocol/vm/vmutil"
9 // MapTx converts a types TxData object into its entries-based
11 func MapTx(oldTx *TxData) *bytom.Tx {
12 txID, txHeader, entries := mapTx(oldTx)
17 InputIDs: make([]bytom.Hash, len(oldTx.Inputs)),
20 spentOutputIDs := make(map[bytom.Hash]bool)
21 for id, e := range entries {
23 switch e := e.(type) {
29 spentOutputIDs[*e.SpentOutputId] = true
30 if *e.WitnessDestination.Value.AssetId == *bytom.BTMAssetID {
31 tx.GasInputIDs = append(tx.GasInputIDs, id)
41 if ord >= uint64(len(oldTx.Inputs)) {
47 for id := range spentOutputIDs {
48 tx.SpentOutputIDs = append(tx.SpentOutputIDs, id)
53 func mapTx(tx *TxData) (headerID bytom.Hash, hdr *bytom.TxHeader, entryMap map[bytom.Hash]bytom.Entry) {
54 entryMap = make(map[bytom.Hash]bytom.Entry)
55 addEntry := func(e bytom.Entry) bytom.Hash {
56 id := bytom.EntryID(e)
63 issuances []*bytom.Issuance
64 coinbase *bytom.Coinbase
67 muxSources := make([]*bytom.ValueSource, len(tx.Inputs))
68 for i, input := range tx.Inputs {
69 switch inp := input.TypedInput.(type) {
71 nonceHash := inp.NonceHash()
72 assetDefHash := inp.AssetDefinitionHash()
73 value := input.AssetAmount()
75 issuance := bytom.NewIssuance(&nonceHash, &value, uint64(i))
76 issuance.WitnessAssetDefinition = &bytom.AssetDefinition{
78 IssuanceProgram: &bytom.Program{
79 VmVersion: inp.VMVersion,
80 Code: inp.IssuanceProgram,
83 issuance.WitnessArguments = inp.Arguments
84 issuanceID := addEntry(issuance)
86 muxSources[i] = &bytom.ValueSource{
90 issuances = append(issuances, issuance)
93 // create entry for prevout
94 prog := &bytom.Program{VmVersion: inp.VMVersion, Code: inp.ControlProgram}
95 src := &bytom.ValueSource{
97 Value: &inp.AssetAmount,
98 Position: inp.SourcePosition,
100 prevout := bytom.NewOutput(src, prog, 0) // ordinal doesn't matter for prevouts, only for result outputs
101 prevoutID := addEntry(prevout)
102 // create entry for spend
103 spend := bytom.NewSpend(&prevoutID, uint64(i))
104 spend.WitnessArguments = inp.Arguments
105 spendID := addEntry(spend)
107 muxSources[i] = &bytom.ValueSource{
109 Value: &inp.AssetAmount,
111 spends = append(spends, spend)
114 coinbase = bytom.NewCoinbase(inp.Arbitrary)
115 coinbaseID := addEntry(coinbase)
118 muxSources[i] = &bytom.ValueSource{
120 Value: &out.AssetAmount,
125 mux := bytom.NewMux(muxSources, &bytom.Program{VmVersion: 1, Code: []byte{byte(vm.OP_TRUE)}})
126 muxID := addEntry(mux)
128 // connect the inputs to the mux
129 for _, spend := range spends {
130 spentOutput := entryMap[*spend.SpentOutputId].(*bytom.Output)
131 spend.SetDestination(&muxID, spentOutput.Source.Value, spend.Ordinal)
133 for _, issuance := range issuances {
134 issuance.SetDestination(&muxID, issuance.Value, issuance.Ordinal)
138 coinbase.SetDestination(&muxID, mux.Sources[0].Value, 0)
141 // convert types.outputs to the bytom.output
142 var resultIDs []*bytom.Hash
143 for i, out := range tx.Outputs {
144 src := &bytom.ValueSource{
146 Value: &out.AssetAmount,
149 var resultID bytom.Hash
150 if vmutil.IsUnspendable(out.ControlProgram) {
152 r := bytom.NewRetirement(src, uint64(i))
153 resultID = addEntry(r)
156 prog := &bytom.Program{out.VMVersion, out.ControlProgram}
157 o := bytom.NewOutput(src, prog, uint64(i))
158 resultID = addEntry(o)
161 dest := &bytom.ValueDestination{
166 resultIDs = append(resultIDs, &resultID)
167 mux.WitnessDestinations = append(mux.WitnessDestinations, dest)
170 h := bytom.NewTxHeader(tx.Version, tx.SerializedSize, tx.TimeRange, resultIDs)
171 return addEntry(h), h, entryMap
174 func mapBlockHeader(old *BlockHeader) (bytom.Hash, *bytom.BlockHeader) {
175 bh := bytom.NewBlockHeader(old.Version, old.Height, &old.PreviousBlockHash, old.Timestamp, &old.TransactionsMerkleRoot, &old.TransactionStatusHash, old.Nonce, old.Bits)
176 return bytom.EntryID(bh), bh
179 // MapBlock converts a types block to bc block
180 func MapBlock(old *Block) *bytom.Block {
185 b := new(bytom.Block)
186 b.ID, b.BlockHeader = mapBlockHeader(&old.BlockHeader)
187 for _, oldTx := range old.Transactions {
188 b.Transactions = append(b.Transactions, oldTx.Tx)