github.com/aergoio/aergo@v1.3.1/cmd/aergocli/util/base58addr.go (about)

     1  package util
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"math/big"
     7  	"strconv"
     8  	"time"
     9  
    10  	"github.com/aergoio/aergo/types"
    11  	"github.com/mr-tron/base58/base58"
    12  )
    13  
    14  type InOutTx struct {
    15  	Hash string
    16  	Body *InOutTxBody
    17  }
    18  
    19  type InOutTxBody struct {
    20  	Nonce       uint64
    21  	Account     string
    22  	Recipient   string
    23  	Amount      string
    24  	Payload     string
    25  	GasLimit    uint64
    26  	GasPrice    string
    27  	Type        types.TxType
    28  	ChainIdHash string
    29  	Sign        string
    30  }
    31  
    32  type InOutTxIdx struct {
    33  	BlockHash string
    34  	Idx       int32
    35  }
    36  
    37  type InOutTxInBlock struct {
    38  	TxIdx *InOutTxIdx
    39  	Tx    *InOutTx
    40  }
    41  
    42  type InOutBlockHeader struct {
    43  	ChainID          string
    44  	PrevBlockHash    string
    45  	BlockNo          uint64
    46  	Timestamp        int64
    47  	BlockRootHash    string
    48  	TxRootHash       string
    49  	ReceiptsRootHash string
    50  	Confirms         uint64
    51  	PubKey           string
    52  	Sign             string
    53  	CoinbaseAccount  string
    54  }
    55  
    56  type InOutBlockBody struct {
    57  	Txs []*InOutTx
    58  }
    59  
    60  type InOutBlock struct {
    61  	Hash   string
    62  	Header InOutBlockHeader
    63  	Body   InOutBlockBody
    64  }
    65  
    66  type InOutBlockIdx struct {
    67  	BlockHash string
    68  	BlockNo   uint64
    69  }
    70  
    71  type InOutPeerAddress struct {
    72  	Address string
    73  	Port    string
    74  	PeerId  string
    75  }
    76  
    77  type InOutPeer struct {
    78  	Address   InOutPeerAddress
    79  	BestBlock InOutBlockIdx
    80  	LastCheck time.Time
    81  	State     string
    82  	Hidden    bool
    83  	Self      bool
    84  	Version   string
    85  }
    86  
    87  func FillTxBody(source *InOutTxBody, target *types.TxBody) error {
    88  	var err error
    89  	if source == nil {
    90  		return errors.New("tx body is empty")
    91  	}
    92  	target.Nonce = source.Nonce
    93  	if source.Account != "" {
    94  		target.Account, err = types.DecodeAddress(source.Account)
    95  		if err != nil {
    96  			return err
    97  		}
    98  	}
    99  	if source.Recipient != "" {
   100  		target.Recipient, err = types.DecodeAddress(source.Recipient)
   101  		if err != nil {
   102  			return err
   103  		}
   104  	}
   105  	if source.Amount != "" {
   106  		amount, err := ParseUnit(source.Amount)
   107  		if err != nil {
   108  			return err
   109  		}
   110  		target.Amount = amount.Bytes()
   111  	}
   112  	if source.Payload != "" {
   113  		target.Payload, err = base58.Decode(source.Payload)
   114  		if err != nil {
   115  			return err
   116  		}
   117  	}
   118  	target.GasLimit = source.GasLimit
   119  	if source.GasPrice != "" {
   120  		price, err := ParseUnit(source.GasPrice)
   121  		if err != nil {
   122  			return err
   123  		}
   124  		target.GasPrice = price.Bytes()
   125  	}
   126  	if source.ChainIdHash != "" {
   127  		target.ChainIdHash, err = base58.Decode(source.ChainIdHash)
   128  		if err != nil {
   129  			return err
   130  		}
   131  	}
   132  	if source.Sign != "" {
   133  		target.Sign, err = base58.Decode(source.Sign)
   134  		if err != nil {
   135  			return err
   136  		}
   137  	}
   138  	target.Type = source.Type
   139  	return nil
   140  }
   141  
   142  func ParseBase58Tx(jsonTx []byte) ([]*types.Tx, error) {
   143  	var inputlist []InOutTx
   144  	err := json.Unmarshal([]byte(jsonTx), &inputlist)
   145  	if err != nil {
   146  		var input InOutTx
   147  		err = json.Unmarshal([]byte(jsonTx), &input)
   148  		if err != nil {
   149  			return nil, err
   150  		}
   151  		inputlist = append(inputlist, input)
   152  	}
   153  	txs := make([]*types.Tx, len(inputlist))
   154  	for i, in := range inputlist {
   155  		tx := &types.Tx{Body: &types.TxBody{}}
   156  		if in.Hash != "" {
   157  			tx.Hash, err = base58.Decode(in.Hash)
   158  			if err != nil {
   159  				return nil, err
   160  			}
   161  		}
   162  		err = FillTxBody(in.Body, tx.Body)
   163  		if err != nil {
   164  			return nil, err
   165  		}
   166  		txs[i] = tx
   167  	}
   168  
   169  	return txs, nil
   170  }
   171  
   172  func ParseBase58TxBody(jsonTx []byte) (*types.TxBody, error) {
   173  	body := &types.TxBody{}
   174  	in := &InOutTxBody{}
   175  
   176  	err := json.Unmarshal(jsonTx, in)
   177  	if err != nil {
   178  		return nil, err
   179  	}
   180  
   181  	err = FillTxBody(in, body)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  
   186  	return body, nil
   187  }
   188  
   189  func ConvTxEx(tx *types.Tx, payloadType EncodingType) *InOutTx {
   190  	out := &InOutTx{Body: &InOutTxBody{}}
   191  	if tx == nil {
   192  		return out
   193  	}
   194  	out.Hash = base58.Encode(tx.Hash)
   195  	out.Body.Nonce = tx.Body.Nonce
   196  	if tx.Body.Account != nil {
   197  		out.Body.Account = types.EncodeAddress(tx.Body.Account)
   198  	}
   199  	if tx.Body.Recipient != nil {
   200  		out.Body.Recipient = types.EncodeAddress(tx.Body.Recipient)
   201  	}
   202  	out.Body.Amount = new(big.Int).SetBytes(tx.Body.Amount).String()
   203  	switch payloadType {
   204  	case Raw:
   205  		out.Body.Payload = string(tx.Body.Payload)
   206  	case Base58:
   207  		out.Body.Payload = base58.Encode(tx.Body.Payload)
   208  	}
   209  	out.Body.GasLimit = tx.Body.GasLimit
   210  	out.Body.GasPrice = new(big.Int).SetBytes(tx.Body.GasPrice).String()
   211  	out.Body.ChainIdHash = base58.Encode(tx.Body.ChainIdHash)
   212  	out.Body.Sign = base58.Encode(tx.Body.Sign)
   213  	out.Body.Type = tx.Body.Type
   214  	return out
   215  }
   216  
   217  func ConvTx(tx *types.Tx) *InOutTx {
   218  	return ConvTxEx(tx, Base58)
   219  }
   220  
   221  func ConvTxInBlock(txInBlock *types.TxInBlock) *InOutTxInBlock {
   222  	out := &InOutTxInBlock{TxIdx: &InOutTxIdx{}, Tx: &InOutTx{}}
   223  	out.TxIdx.BlockHash = base58.Encode(txInBlock.GetTxIdx().GetBlockHash())
   224  	out.TxIdx.Idx = txInBlock.GetTxIdx().GetIdx()
   225  	out.Tx = ConvTx(txInBlock.GetTx())
   226  	return out
   227  }
   228  
   229  func ConvBlock(b *types.Block) *InOutBlock {
   230  	out := &InOutBlock{}
   231  	if b != nil {
   232  		out.Hash = base58.Encode(b.Hash)
   233  		out.Header.ChainID = base58.Encode(b.GetHeader().GetChainID())
   234  		out.Header.PrevBlockHash = base58.Encode(b.GetHeader().GetPrevBlockHash())
   235  		out.Header.BlockNo = b.GetHeader().GetBlockNo()
   236  		out.Header.Timestamp = b.GetHeader().GetTimestamp()
   237  		out.Header.BlockRootHash = base58.Encode(b.GetHeader().GetBlocksRootHash())
   238  		out.Header.TxRootHash = base58.Encode(b.GetHeader().GetTxsRootHash())
   239  		out.Header.ReceiptsRootHash = base58.Encode(b.GetHeader().GetReceiptsRootHash())
   240  		out.Header.Confirms = b.GetHeader().GetConfirms()
   241  		out.Header.PubKey = base58.Encode(b.GetHeader().GetPubKey())
   242  		out.Header.Sign = base58.Encode(b.GetHeader().GetSign())
   243  		out.Header.CoinbaseAccount = base58.Encode(b.GetHeader().GetCoinbaseAccount())
   244  		if b.Body != nil {
   245  			for _, tx := range b.Body.Txs {
   246  				out.Body.Txs = append(out.Body.Txs, ConvTx(tx))
   247  			}
   248  		}
   249  	}
   250  	return out
   251  }
   252  
   253  func ConvPeer(p *types.Peer) *InOutPeer {
   254  	out := &InOutPeer{}
   255  	out.Address.Address = p.GetAddress().GetAddress()
   256  	out.Address.Port = strconv.Itoa(int(p.GetAddress().GetPort()))
   257  	out.Address.PeerId = base58.Encode(p.GetAddress().GetPeerID())
   258  	out.LastCheck = time.Unix(0, p.GetLashCheck())
   259  	out.BestBlock.BlockNo = p.GetBestblock().GetBlockNo()
   260  	out.BestBlock.BlockHash = base58.Encode(p.GetBestblock().GetBlockHash())
   261  	out.State = types.PeerState(p.State).String()
   262  	out.Hidden = p.Hidden
   263  	out.Self = p.Selfpeer
   264  	if p.Version != "" {
   265  		out.Version = p.Version
   266  	} else {
   267  		out.Version = "(old)"
   268  	}
   269  	return out
   270  }
   271  
   272  func ConvBlockchainStatus(in *types.BlockchainStatus) string {
   273  	out := &InOutBlockchainStatus{}
   274  	if in == nil {
   275  		return ""
   276  	}
   277  	out.Hash = base58.Encode(in.BestBlockHash)
   278  	out.Height = in.BestHeight
   279  
   280  	out.ChainIdHash = base58.Encode(in.BestChainIdHash)
   281  
   282  	toJRM := func(s string) *json.RawMessage {
   283  		if len(s) > 0 {
   284  			m := json.RawMessage(s)
   285  			return &m
   286  		}
   287  		return nil
   288  	}
   289  	out.ConsensusInfo = toJRM(in.ConsensusInfo)
   290  	if in.ChainInfo != nil {
   291  		out.ChainInfo = convChainInfo(in.ChainInfo)
   292  	}
   293  	jsonout, err := json.Marshal(out)
   294  	if err != nil {
   295  		return ""
   296  	}
   297  	return string(jsonout)
   298  }
   299  
   300  func TxConvBase58Addr(tx *types.Tx) string {
   301  	return toString(ConvTx(tx))
   302  }
   303  
   304  type EncodingType int
   305  
   306  const (
   307  	Raw EncodingType = 0 + iota
   308  	Base58
   309  )
   310  
   311  func TxConvBase58AddrEx(tx *types.Tx, payloadType EncodingType) string {
   312  	switch payloadType {
   313  	case Raw:
   314  		return toString(ConvTxEx(tx, Raw))
   315  	case Base58:
   316  		return toString(ConvTxEx(tx, Base58))
   317  	}
   318  	return ""
   319  }
   320  
   321  func TxInBlockConvBase58Addr(txInBlock *types.TxInBlock) string {
   322  	return toString(ConvTxInBlock(txInBlock))
   323  }
   324  
   325  func BlockConvBase58Addr(b *types.Block) string {
   326  	return toString(ConvBlock(b))
   327  }
   328  
   329  func PeerListToString(p *types.PeerList) string {
   330  	peers := []*InOutPeer{}
   331  	for _, peer := range p.GetPeers() {
   332  		peers = append(peers, ConvPeer(peer))
   333  	}
   334  	return toString(peers)
   335  }
   336  
   337  func toString(out interface{}) string {
   338  	jsonout, err := json.MarshalIndent(out, "", " ")
   339  	if err != nil {
   340  		return ""
   341  	}
   342  	return string(jsonout)
   343  }