// class runtx extends Kernel { // run (tx) { // } // } // run tx; the tx message handler // runTx (tx, environment = new Environment()) { // this.environment = environment // if (Buffer.isBuffer(tx) || typeof tx === 'string') { // tx = new Transaction(tx) // if (!tx.valid) { // throw new Error('Invalid transaction signature') // } // } // // look up sender // let fromAccount = this.environment.state.get(tx.from.toString()) // if (!fromAccount) { // throw new Error('Sender account not found: ' + tx.from.toString()) // } // if (fromAccount.get('nonce').gt(tx.nonce)) { // throw new Error(`Invalid nonce: ${fromAccount.get('nonce')} > ${tx.nonce}`) // } // fromAccount.set('nonce', fromAccount.get('nonce').add(new U256(1))) // let isCreation = false // // Special case: contract deployment // if (tx.to.isZero() && (tx.data.length !== 0)) { // console.log('This is a contract deployment transaction') // isCreation = true // } // // This cost will not be refunded // let txCost = 21000 + (isCreation ? 32000 : 0) // tx.data.forEach((item) => { // if (item === 0) { // txCost += 4 // } else { // txCost += 68 // } // }) // if (tx.gasLimit.lt(new U256(txCost))) { // throw new Error(`Minimum transaction gas limit not met: ${txCost}`) // } // if (fromAccount.get('balance').lt(tx.gasLimit.mul(tx.gasPrice))) { // throw new Error(`Insufficient account balance: ${fromAccount.get('balance').toString()} < ${tx.gasLimit.mul(tx.gasPrice).toString()}`) // } // // deduct gasLimit * gasPrice from sender // fromAccount.set('balance', fromAccount.get('balance').sub(tx.gasLimit.mul(tx.gasPrice))) // const handler = isCreation ? this.createHandler.bind(this) : this.callHandler.bind(this) // let ret = handler({ // to: tx.to, // from: tx.from, // gasLimit: tx.gasLimit - txCost, // value: tx.value, // data: tx.data // }) // // refund unused gas // if (ret.executionOutcome === 1) { // fromAccount.set('balance', fromAccount.get('balance').add(tx.gasPrice.mul(ret.gasLeft.add(ret.gasRefund)))) // } // // save new state? // return { // executionOutcome: ret.executionOutcome, // accountCreated: isCreation ? ret.accountCreated : undefined, // returnValue: isCreation ? undefined : ret.returnValue, // gasLeft: ret.gasLeft, // logs: ret.logs // } // }