lib/evm/opFns.js
function (runState, cb) {
    let selfdestructToAddress = runState.stack.pop()
    if (runState.static) {
      trap(ERROR.STATIC_STATE_CHANGE)
    }
    var stateManager = runState.stateManager
    var contract = runState.contract
    var contractAddress = runState.address
    selfdestructToAddress = addressToBuffer(selfdestructToAddress)

    stateManager.getAccount(selfdestructToAddress, function (err, toAccount) {
      // update balances
      if (err) {
        cb(err)
        return
      }

      stateManager.accountIsEmpty(selfdestructToAddress, function (error, empty) {
        if (error) {
          cb(error)
          return
        }

        if ((new BN(contract.balance)).gtn(0)) {
          if (empty) {
            try {
              subGas(runState, new BN(runState._common.param('gasPrices', 'callNewAccount')))
            } catch (e) {
              cb(e.error)
              return
            }
          }
        }

        // only add to refund if this is the first selfdestruct for the address
        if (!runState.selfdestruct[contractAddress.toString('hex')]) {
          runState.gasRefund = runState.gasRefund.addn(runState._common.param('gasPrices', 'selfdestructRefund'))
        }
        runState.selfdestruct[contractAddress.toString('hex')] = selfdestructToAddress
        runState.stopped = true

        var newBalance = new BN(contract.balance).add(new BN(toAccount.balance))
        async.waterfall([
          stateManager.getAccount.bind(stateManager, selfdestructToAddress),
          function (account, cb) {
            account.balance = newBalance
            stateManager.putAccount(selfdestructToAddress, account, cb)
          },
          stateManager.getAccount.bind(stateManager, contractAddress),
          function (account, cb) {
            account.balance = new BN(0)
            stateManager.putAccount(contractAddress, account, cb)
          }
        ], function (err) {
          // The reason for this is to avoid sending an array of results
          cb(err)
        })
      })
    })
  }
function (runState, cb) {
    let selfdestructToAddress = runState.stack.pop()
    if (runState.static) {
      trap(ERROR.STATIC_STATE_CHANGE)
    }
    var stateManager = runState.stateManager
    var contract = runState.contract
    var contractAddress = runState.address
    selfdestructToAddress = addressToBuffer(selfdestructToAddress)

    stateManager.getAccount(selfdestructToAddress, function (err, toAccount) {
      // update balances
      if (err) {
        cb(err)
        return
      }

      stateManager.accountIsEmpty(selfdestructToAddress, function (error, empty) {
        if (error) {
          cb(error)
          return
        }

        if ((new BN(contract.balance)).gtn(0)) {
          if (empty) {
            try {
              subGas(runState, new BN(runState._common.param('gasPrices', 'callNewAccount')))
            } catch (e) {
              cb(e.error)
              return
            }
          }
        }

        // only add to refund if this is the first selfdestruct for the address
        if (!runState.selfdestruct[contractAddress.toString('hex')]) {
          runState.gasRefund = runState.gasRefund.addn(runState._common.param('gasPrices', 'selfdestructRefund'))
        }
        runState.selfdestruct[contractAddress.toString('hex')] = selfdestructToAddress
        runState.stopped = true

        var newBalance = new BN(contract.balance).add(new BN(toAccount.balance))
        async.waterfall([
          stateManager.getAccount.bind(stateManager, selfdestructToAddress),
          function (account, cb) {
            account.balance = newBalance
            stateManager.putAccount(selfdestructToAddress, account, cb)
          },
          stateManager.getAccount.bind(stateManager, contractAddress),
          function (account, cb) {
            account.balance = new BN(0)
            stateManager.putAccount(contractAddress, account, cb)
          }
        ], function (err) {
          // The reason for this is to avoid sending an array of results
          cb(err)
        })
      })
    })
  }
function ( runState , cb ) { let selfdestructToAddress = runState . stack . pop ( ) if ( runState . static ) { trap ( ERROR . STATIC_STATE_CHANGE ) } var stateManager = runState . stateManager var contract = runState . contract var contractAddress = runState . address selfdestructToAddress = addressToBuffer ( selfdestructToAddress ) stateManager . getAccount ( selfdestructToAddress , function ( err , toAccount ) { // update balances if ( err ) { cb ( err ) return } stateManager . accountIsEmpty ( selfdestructToAddress , function ( error , empty ) { if ( error ) { cb ( error ) return } if ( ( new BN ( contract . balance ) ) . gtn ( 0 ) ) { if ( empty ) { try { subGas ( runState , new BN ( runState . _common . param ( 'gasPrices' , 'callNewAccount' ) ) ) } catch ( e ) { cb ( e . error ) return } } } // only add to refund if this is the first selfdestruct for the address if ( ! runState . selfdestruct [ contractAddress . toString ( 'hex' ) ] ) { runState . gasRefund = runState . gasRefund . addn ( runState . _common . param ( 'gasPrices' , 'selfdestructRefund' ) ) } runState . selfdestruct [ contractAddress . toString ( 'hex' ) ] = selfdestructToAddress runState . stopped = true var newBalance = new BN ( contract . balance ) . add ( new BN ( toAccount . balance ) ) async . waterfall ( [ stateManager . getAccount . bind ( stateManager , selfdestructToAddress ) , function ( account , cb ) { account . balance = newBalance stateManager . putAccount ( selfdestructToAddress , account , cb ) } , stateManager . getAccount . bind ( stateManager , contractAddress ) , function ( account , cb ) { account . balance = new BN ( 0 ) stateManager . putAccount ( contractAddress , account , cb ) } ] , function ( err ) { // The reason for this is to avoid sending an array of results cb ( err ) } ) } ) } ) }
'0x70', range - other
0x70 range - other