github.com/klaytn/klaytn@v1.12.1/datasync/dbsyncer/tx_record.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package dbsyncer 18 19 import ( 20 "strings" 21 22 "github.com/klaytn/klaytn/blockchain/types" 23 "github.com/klaytn/klaytn/common" 24 "github.com/klaytn/klaytn/common/hexutil" 25 ) 26 27 type SummaryArguments struct { 28 from string 29 txHash string 30 to string 31 contractAddress string 32 33 tx *types.Transaction 34 } 35 36 type TxMapArguments struct { 37 senderTxHash string 38 txHash string 39 } 40 41 type TxReceiptArgument struct { 42 tx *types.Transaction 43 receipt *types.Receipt 44 } 45 46 type BulkInsertQuery struct { 47 parameters string 48 vals []interface{} 49 blockNumber uint64 50 insertCount int 51 } 52 53 func MakeTxDBRow(block *types.Block, txKey uint64, tx *types.Transaction, receipt *types.Receipt) (string, []interface{}, TxMapArguments, SummaryArguments, error) { 54 cols := "" 55 vals := []interface{}{} 56 57 blockHash := block.Hash().Hex() 58 blockNumber := block.Number().Uint64() 59 60 contractAddress := "" 61 if (receipt.ContractAddress != common.Address{}) { 62 contractAddress = strings.ToLower(receipt.ContractAddress.Hex()) 63 } 64 65 from := "" 66 if tx.IsEthereumTransaction() { 67 signer := types.LatestSignerForChainID(tx.ChainId()) 68 addr, err := types.Sender(signer, tx) 69 if err != nil { 70 logger.Error("fail to tx.From", "err", err) 71 return "", []interface{}{}, TxMapArguments{}, SummaryArguments{}, err 72 } 73 from = strings.ToLower(addr.Hex()) 74 } else { 75 addr, err := tx.From() 76 if err != nil { 77 logger.Error("fail to tx.From", "err", err) 78 return "", []interface{}{}, TxMapArguments{}, SummaryArguments{}, err 79 } 80 from = strings.ToLower(addr.Hex()) 81 } 82 83 gas := tx.Gas() 84 txGasPrice := tx.GasPrice().String() 85 txGasUsed := receipt.GasUsed 86 87 input := hexutil.Bytes(tx.Data()).String() 88 if input == "0x" { 89 input = "" 90 } 91 92 nonce := tx.Nonce() 93 status := receipt.Status 94 to := "" // '' means that address doesn't exist 95 if tx.To() != nil { 96 to = strings.ToLower(tx.To().Hex()) 97 } 98 timestamp := block.Time().Uint64() 99 txHash := tx.Hash().Hex() 100 txtype := tx.Type().String() 101 value := tx.Value().String() 102 103 feePayer := "" 104 feeRatio := uint8(0) 105 if tx.IsFeeDelegatedTransaction() { 106 feeAddr, err := tx.FeePayer() 107 if err != nil { 108 logger.Error("fail to tx.FeePayer", "err", err) 109 return "", []interface{}{}, TxMapArguments{}, SummaryArguments{}, err 110 } 111 ratio, _ := tx.FeeRatio() 112 // ok is false in TxTypeFeeDelegatedValueTransfer 113 // ok is true in TxTypeFeeDelegatedValueTransferWithRatio 114 115 feePayer = strings.ToLower(feeAddr.Hex()) 116 feeRatio = uint8(ratio) 117 } 118 119 senderHash := "" 120 if senderTxHash, ok := tx.SenderTxHash(); ok { 121 senderHash = senderTxHash.Hex() 122 } 123 124 cols = "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" 125 vals = append(vals, txKey, blockHash, blockNumber, contractAddress, from, gas, txGasPrice, txGasUsed, input, nonce, status, to, 126 timestamp, txHash, txtype, value, feePayer, feeRatio, senderHash) 127 128 TxMapArg := TxMapArguments{senderHash, txHash} 129 summaryArg := SummaryArguments{from, txHash, to, contractAddress, tx} 130 131 return cols, vals, TxMapArg, summaryArg, nil 132 } 133 134 func MakeSummaryDBRow(sa SummaryArguments) (cols string, vals []interface{}, count int, err error) { 135 // insert account summary for creation and deploy 136 if !sa.tx.IsEthereumTransaction() { 137 if sa.tx.Type().IsAccountCreation() { 138 accountType := 0 139 creator := sa.from 140 createdTx := sa.txHash 141 142 hra := true 143 // TODO-Klaytn need to use humanreable field 144 internalTx, ok := sa.tx.GetTxInternalData().(*types.TxInternalDataAccountCreation) 145 if !ok { 146 logger.Error("fail to convert TxInternalDataAccountCreation", "txhash", sa.tx.Hash().Hex()) 147 hra = false 148 } else { 149 hra = internalTx.HumanReadable 150 } 151 152 cols = "(?,?,?,?,?)" 153 vals = append(vals, sa.to, accountType, creator, createdTx, hra) 154 155 count = 1 156 157 } else if sa.tx.Type().IsContractDeploy() { 158 accountType := 1 159 creator := sa.from 160 createdTx := sa.txHash 161 162 // TODO-Klaytn need to use humanreable field 163 hra := false 164 165 switch internalTx := sa.tx.GetTxInternalData().(type) { 166 case *types.TxInternalDataSmartContractDeploy: 167 hra = internalTx.HumanReadable 168 case *types.TxInternalDataFeeDelegatedSmartContractDeploy: 169 hra = internalTx.HumanReadable 170 case *types.TxInternalDataFeeDelegatedSmartContractDeployWithRatio: 171 hra = internalTx.HumanReadable 172 default: 173 logger.Error("fail to convert ", "type", internalTx, "txhash", sa.tx.Hash().Hex()) 174 } 175 176 cols = "(?,?,?,?,?)" 177 vals = append(vals, sa.contractAddress, accountType, creator, createdTx, hra) 178 179 count = 1 180 } 181 } else if sa.contractAddress != "" { 182 // AccountCreation for LegacyTransaction 183 accountType := 1 184 creator := sa.from 185 createdTx := sa.txHash 186 187 cols = "(?,?,?,?,?)" 188 vals = append(vals, sa.contractAddress, accountType, creator, createdTx, false) 189 190 count = 1 191 } 192 193 return cols, vals, count, nil 194 } 195 196 func MakeTxMappingRow(tm TxMapArguments) (cols string, vals []interface{}, count int, err error) { 197 if tm.senderTxHash != "" { 198 cols = "(?,?)" 199 vals = append(vals, tm.senderTxHash, tm.txHash) 200 201 count = 1 202 } 203 204 return cols, vals, count, nil 205 }