import { BUFFER_EMPTY , Data , Quantity } from "@ganache/utils" ; import { Address } from "@ganache/ethereum-address" ; import type Common from "@ethereumjs/common" ; import { Hardfork } from "./hardfork" ; import { Params } from "./params" ; import { GanacheRawExtraTx } from "./raw" ; const MAX_UINT64 = 1n << ( 64n - 1n ) ; param data param hasToAddress param common returns export const calculateIntrinsicGas = ( data , hasToAddress , common ) => { const hardfork = common . hardfork ( ) as Hardfork ; let gas = Params . TRANSACTION_GAS ; if ( ! hasToAddress ) gas += Params . TRANSACTION_CREATION ; if ( data ) { const input = data . toBuffer ( ) ; const dataLength = input . byteLength ; if ( dataLength > 0 ) { const TRANSACTION_DATA_NON_ZERO_GAS = Params . TRANSACTION_DATA_NON_ZERO_GAS . get ( hardfork ) ; const TRANSACTION_DATA_ZERO_GAS = Params . TRANSACTION_DATA_ZERO_GAS ; let nonZeroBytes = 0n ; for ( const b of input ) { if ( b !== 0 ) { nonZeroBytes ++ ; } } if ( ( MAX_UINT64 - gas ) / TRANSACTION_DATA_NON_ZERO_GAS < nonZeroBytes ) { return - 1n ; } gas += nonZeroBytes * TRANSACTION_DATA_NON_ZERO_GAS ; const zeroBytes = BigInt ( dataLength ) - nonZeroBytes ; if ( ( MAX_UINT64 - gas ) / TRANSACTION_DATA_ZERO_GAS < zeroBytes ) { return - 1n ; } gas += zeroBytes * TRANSACTION_DATA_ZERO_GAS ; } } return gas ; } ; export class BaseTransaction { public type : Quantity ; public nonce : Quantity ; public gas : Quantity ; public to : Address | null ; public value : Quantity ; public data : Data ; public v : Quantity | null ; public r : Quantity | null ; public s : Quantity | null ; public effectiveGasPrice : Quantity ; public from : Address | null ; public common : Common ; public index : Quantity ; public hash : Data ; public blockNumber : Quantity ; public blockHash : Data ; constructor ( common , extra ? ) { this . common = common ; if ( extra ) { this . setExtra ( extra ) ; } } public setExtra ( raw ) { const [ from , hash , blockHash , blockNumber , index , effectiveGasPrice ] = raw ; this . from = Address . from ( from ) ; this . hash = Data . from ( hash , 32 ) ; this . blockHash = Data . from ( blockHash , 32 ) ; this . blockNumber = Quantity . from ( blockNumber ) ; this . index = Quantity . from ( index ) ; this . effectiveGasPrice = Quantity . from ( effectiveGasPrice ) ; } public calculateIntrinsicGas ( ) { const hasToAddress = this . to != null && ! this . to . toBuffer ( ) . equals ( BUFFER_EMPTY ) ; return calculateIntrinsicGas ( this . data , hasToAddress , this . common ) ; } }