aergoio/aergo

View on GitHub
types/jsonrpc/tx.go

Summary

Maintainability
A
3 hrs
Test Coverage
package jsonrpc

import (
    "encoding/json"
    "errors"
    "math/big"

    "github.com/aergoio/aergo/v2/internal/enc/base58"
    "github.com/aergoio/aergo/v2/types"
)

func ParseBase58Tx(jsonTx []byte) ([]*types.Tx, error) {
    var inputlist []InOutTx
    err := json.Unmarshal([]byte(jsonTx), &inputlist)
    if err != nil {
        var input InOutTx
        err = json.Unmarshal([]byte(jsonTx), &input)
        if err != nil {
            return nil, err
        }
        inputlist = append(inputlist, input)
    }
    txs := make([]*types.Tx, len(inputlist))
    for i, in := range inputlist {
        tx := &types.Tx{Body: &types.TxBody{}}
        if in.Hash != "" {
            tx.Hash, err = base58.Decode(in.Hash)
            if err != nil {
                return nil, err
            }
        }
        tx.Body, err = ParseTxBody(in.Body)
        if err != nil {
            return nil, err
        }
        txs[i] = tx
    }

    return txs, nil
}

func ParseBase58TxBody(jsonTx []byte) (*types.TxBody, error) {
    in := &InOutTxBody{}
    err := json.Unmarshal(jsonTx, in)
    if err != nil {
        return nil, err
    }

    body, err := ParseTxBody(in)
    if err != nil {
        return nil, err
    }

    return body, nil
}

//-----------------------------------------------------------------------//
//

func ConvTx(msg *types.Tx, payloadType EncodingType) (tx *InOutTx) {
    if msg == nil {
        return nil
    }
    tx = &InOutTx{}
    tx.Body = &InOutTxBody{}
    if msg == nil {
        return
    }
    tx.Hash = base58.Encode(msg.Hash)
    if msg.Body != nil {
        tx.Body = ConvTxBody(msg.Body, payloadType)
    }

    return tx
}

type InOutTx struct {
    Hash string       `json:"hash,omitempty"`
    Body *InOutTxBody `json:"body,omitempty"`
}

func (t *InOutTx) String() string {
    return MarshalJSON(t)
}

func ConvTxBody(msg *types.TxBody, payloadType EncodingType) *InOutTxBody {
    if msg == nil {
        return nil
    }

    tb := &InOutTxBody{}
    tb.Nonce = msg.Nonce
    if msg.Account != nil {
        tb.Account = types.EncodeAddress(msg.Account)
    }
    if msg.Recipient != nil {
        tb.Recipient = types.EncodeAddress(msg.Recipient)
    }
    if msg.Amount != nil {
        tb.Amount = new(big.Int).SetBytes(msg.Amount).String()
    }
    switch payloadType {
    case Raw:
        tb.Payload = string(msg.Payload)
    case Base58:
        tb.Payload = base58.Encode(msg.Payload)
    }
    tb.GasLimit = msg.GasLimit
    if msg.GasPrice != nil {
        tb.GasPrice = new(big.Int).SetBytes(msg.GasPrice).String()
    }
    tb.ChainIdHash = base58.Encode(msg.ChainIdHash)
    tb.Sign = base58.Encode(msg.Sign)
    tb.Type = msg.Type
    return tb
}

func ParseTxBody(tb *InOutTxBody) (msg *types.TxBody, err error) {
    if tb == nil {
        return nil, errors.New("tx body is empty")
    }
    msg = &types.TxBody{}

    msg.Nonce = tb.Nonce
    if tb.Account != "" {
        msg.Account, err = types.DecodeAddress(tb.Account)
        if err != nil {
            return nil, err
        }
    }
    if tb.Recipient != "" {
        msg.Recipient, err = types.DecodeAddress(tb.Recipient)
        if err != nil {
            return nil, err
        }
    }
    if tb.Amount != "" {
        amount, err := ParseUnit(tb.Amount)
        if err != nil {
            return nil, err
        }
        msg.Amount = amount.Bytes()
    }
    if tb.Payload != "" {
        msg.Payload, err = base58.Decode(tb.Payload)
        if err != nil {
            return nil, err
        }
    }

    if tb.PayloadJson != nil && tb.PayloadJson.Name != "" {
        payload, err := json.Marshal(tb.PayloadJson)

        if err != nil {
            return nil, err
        } else {
            msg.Payload = payload
        }
    }

    msg.GasLimit = tb.GasLimit
    if tb.GasPrice != "" {
        price, err := ParseUnit(tb.GasPrice)
        if err != nil {
            return nil, err
        }
        msg.GasPrice = price.Bytes()
    }
    if tb.ChainIdHash != "" {
        msg.ChainIdHash, err = base58.Decode(tb.ChainIdHash)
        if err != nil {
            return nil, err
        }
    }
    if tb.Sign != "" {
        msg.Sign, err = base58.Decode(tb.Sign)
        if err != nil {
            return nil, err
        }
    }
    msg.Type = tb.Type
    return msg, nil
}

type InOutPayload struct {
    Name string        `json:"name,omitempty"`
    Arg  []interface{} `json:"arg,omitempty"`
}

type InOutTxBody struct {
    Nonce       uint64          `json:"nonce,omitempty"`
    Account     string          `json:"account,omitempty"`
    Recipient   string          `json:"recipient,omitempty"`
    Amount      string          `json:"amount,omitempty"`
    Payload     string          `json:"payload,omitempty"`
    PayloadJson *types.CallInfo `json:"payloadJson,omitempty"`
    GasLimit    uint64          `json:"gasLimit,omitempty"`
    GasPrice    string          `json:"gasPrice,omitempty"`
    Type        types.TxType    `json:"type,omitempty"`
    ChainIdHash string          `json:"chainIdHash,omitempty"`
    Sign        string          `json:"sign,omitempty"`
}

func (b *InOutTxBody) String() string {
    return MarshalJSON(b)
}

func ConvTxInBlock(msg *types.TxInBlock, payloadType EncodingType) *InOutTxInBlock {
    if msg == nil {
        return nil
    }
    tib := &InOutTxInBlock{}
    tib.Tx = ConvTx(msg.GetTx(), payloadType)
    tib.TxIdx = ConvTxIdx(msg.GetTxIdx())
    return tib
}

type InOutTxInBlock struct {
    TxIdx *InOutTxIdx `json:"txIdx"`
    Tx    *InOutTx    `json:"tx"`
}

func ConvTxIdx(msg *types.TxIdx) *InOutTxIdx {
    if msg == nil {
        return nil
    }
    return &InOutTxIdx{
        BlockHash: base58.Encode(msg.GetBlockHash()),
        Idx:       msg.GetIdx(),
    }
}

type InOutTxIdx struct {
    BlockHash string `json:"blockHash,omitempty"`
    Idx       int32  `json:"idx,omitempty"`
}

func (t *InOutTxInBlock) String() string {
    return MarshalJSON(t)
}

func CovPayloadJson(tx *InOutTx) {
    if tx.Body.Payload != "" {
        payload, err := base58.Decode(tx.Body.Payload)
        if err == nil {
            tx.Body.PayloadJson = &types.CallInfo{}
            _ = json.Unmarshal(payload, tx.Body.PayloadJson)
        }
    }
}