diff --git a/core/chain_manager.go b/core/chain_manager.go
index 959bfd3986603e4aa5d9dff220f48b3ccc5396fe..2f6c36382154454ceb221061b21b9d99c056dbb7 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -28,11 +28,13 @@ type StateQuery interface {
 func CalcDifficulty(block, parent *types.Block) *big.Int {
 	diff := new(big.Int)
 
-	adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
-	if block.Time() >= parent.Time()+8 {
-		diff.Sub(parent.Difficulty(), adjust)
-	} else {
+	//adjust := new(big.Int).Rsh(parent.Difficulty(), 10)
+	//if block.Time() >= parent.Time()+8 {
+	adjust := new(big.Int).Div(parent.Difficulty(), big.NewInt(2048))
+	if (block.Time() - parent.Time()) < 8 {
 		diff.Add(parent.Difficulty(), adjust)
+	} else {
+		diff.Sub(parent.Difficulty(), adjust)
 	}
 
 	return diff
diff --git a/core/state_transition.go b/core/state_transition.go
index 7331fdd4a58a7b5e73ce031a6d6611281e47cbe5..8626504f91689dda64bf40480329d915f188bf4a 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -12,6 +12,12 @@ import (
 
 const tryJit = false
 
+var (
+	GasTx            = big.NewInt(21000)
+	GasTxNonZeroByte = big.NewInt(37)
+	GasTxZeroByte    = big.NewInt(2)
+)
+
 /*
  * The State transitioning model
  *
@@ -170,7 +176,7 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 	//sender.Nonce += 1
 
 	// Transaction gas
-	if err = self.UseGas(vm.GasTx); err != nil {
+	if err = self.UseGas(GasTx); err != nil {
 		return
 	}
 
@@ -178,9 +184,9 @@ func (self *StateTransition) TransitionState() (ret []byte, err error) {
 	var dgas int64
 	for _, byt := range self.data {
 		if byt != 0 {
-			dgas += vm.GasData.Int64()
+			dgas += GasTxNonZeroByte.Int64()
 		} else {
-			dgas += 1 // This is 1/5. If GasData changes this fails
+			dgas += GasTxZeroByte.Int64()
 		}
 	}
 	if err = self.UseGas(big.NewInt(dgas)); err != nil {
diff --git a/vm/address.go b/vm/address.go
index 1c9369ab73d94de954ab7cb03c9a1c5e03faaca6..b1345da8f97b97cbac864fed0de915559e1ccd70 100644
--- a/vm/address.go
+++ b/vm/address.go
@@ -32,23 +32,23 @@ func PrecompiledContracts() map[string]*PrecompiledAccount {
 
 		// SHA256
 		string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int {
-			n := big.NewInt(int64(l+31)/32 + 1)
-			n.Mul(n, GasSha256)
-			return n
+			n := big.NewInt(int64(l+31) / 32)
+			n.Mul(n, GasSha256Word)
+			return n.Add(n, GasSha256Base)
 		}, sha256Func},
 
 		// RIPEMD160
 		string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int {
-			n := big.NewInt(int64(l+31)/32 + 1)
-			n.Mul(n, GasRipemd)
-			return n
+			n := big.NewInt(int64(l+31) / 32)
+			n.Mul(n, GasRipemdWord)
+			return n.Add(n, GasRipemdBase)
 		}, ripemd160Func},
 
 		string(ethutil.LeftPadBytes([]byte{4}, 20)): &PrecompiledAccount{func(l int) *big.Int {
-			n := big.NewInt(int64(l+31)/32 + 1)
-			n.Mul(n, GasMemCpy)
+			n := big.NewInt(int64(l+31) / 32)
+			n.Mul(n, GasIdentityWord)
 
-			return n
+			return n.Add(n, GasIdentityBase)
 		}, memCpy},
 	}
 }
diff --git a/vm/common.go b/vm/common.go
index 45a7187a99084664ee134e19c181a4064e70eb98..bc135300953f1f6b935cd8c5a130a00dfe71d28a 100644
--- a/vm/common.go
+++ b/vm/common.go
@@ -31,26 +31,48 @@ func NewVm(env Environment) VirtualMachine {
 }
 
 var (
-	GasStep         = big.NewInt(1)
-	GasSha          = big.NewInt(10)
-	GasSLoad        = big.NewInt(20)
-	GasSStore       = big.NewInt(100)
-	GasSStoreRefund = big.NewInt(100)
-	GasBalance      = big.NewInt(20)
-	GasCreate       = big.NewInt(100)
-	GasCall         = big.NewInt(20)
-	GasCreateByte   = big.NewInt(5)
-	GasSha3Byte     = big.NewInt(10)
-	GasSha256Byte   = big.NewInt(50)
-	GasRipemdByte   = big.NewInt(50)
-	GasMemory       = big.NewInt(1)
-	GasData         = big.NewInt(5)
-	GasTx           = big.NewInt(500)
-	GasLog          = big.NewInt(32)
-	GasSha256       = big.NewInt(50)
-	GasRipemd       = big.NewInt(50)
-	GasEcrecover    = big.NewInt(500)
-	GasMemCpy       = big.NewInt(1)
+	GasQuickStep   = big.NewInt(2)
+	GasFastestStep = big.NewInt(3)
+	GasFastStep    = big.NewInt(5)
+	GasMidStep     = big.NewInt(8)
+	GasSlowStep    = big.NewInt(10)
+	GasExtStep     = big.NewInt(20)
+
+	GasStorageGet        = big.NewInt(50)
+	GasStorageAdd        = big.NewInt(20000)
+	GasStorageMod        = big.NewInt(5000)
+	GasLogBase           = big.NewInt(2000)
+	GasLogTopic          = big.NewInt(2000)
+	GasLogData           = big.NewInt(8)
+	GasCreate            = big.NewInt(32000)
+	GasCreateByte        = big.NewInt(300)
+	GasCall              = big.NewInt(40)
+	GasCallValueTransfer = big.NewInt(6700)
+	GasCallNewAccount    = big.NewInt(25000)
+	GasReturn            = big.NewInt(0)
+	GasStop              = big.NewInt(0)
+	GasJumpDest          = big.NewInt(1)
+
+	RefundStorage = big.NewInt(15000)
+	RefundSuicide = big.NewInt(24000)
+
+	GasMemWord           = big.NewInt(3)
+	GasQuadCoeffWord     = big.NewInt(1)
+	GasContractByte      = big.NewInt(200)
+	GasTransaction       = big.NewInt(21000)
+	GasTxDataNonzeroByte = big.NewInt(37)
+	GasTxZeroByte        = big.NewInt(2)
+
+	GasSha3Base     = big.NewInt(30)
+	GasSha3Word     = big.NewInt(6)
+	GasSha256Base   = big.NewInt(60)
+	GasSha256Word   = big.NewInt(12)
+	GasRipemdBase   = big.NewInt(600)
+	GasRipemdWord   = big.NewInt(12)
+	GasEcrecover    = big.NewInt(3000)
+	GasIdentityBase = big.NewInt(15)
+	GasIdentityWord = big.NewInt(3)
+	GasCopyWord     = big.NewInt(3)
 
 	Pow256 = ethutil.BigPow(2, 256)
 
@@ -59,6 +81,8 @@ var (
 
 	U256 = ethutil.U256
 	S256 = ethutil.S256
+
+	Zero = ethutil.Big0
 )
 
 const MaxCallDepth = 1025
diff --git a/vm/vm.go b/vm/vm.go
index b9282435e3cc16869d09904969f3ee0ba8141411..791718fb2fb69a263d950f101213dda9f62cd501 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -769,27 +769,97 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
 	}
 }
 
-func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
-	gas := new(big.Int)
-	addStepGasUsage := func(amount *big.Int) {
-		if amount.Cmp(ethutil.Big0) >= 0 {
-			gas.Add(gas, amount)
-		}
+type req struct {
+	stack int
+	gas   *big.Int
+}
+
+var _baseCheck = map[OpCode]req{
+	//       Req Stack  Gas price
+	ADD:          {2, GasFastestStep},
+	LT:           {2, GasFastestStep},
+	GT:           {2, GasFastestStep},
+	SLT:          {2, GasFastestStep},
+	SGT:          {2, GasFastestStep},
+	EQ:           {2, GasFastestStep},
+	ISZERO:       {1, GasFastestStep},
+	SUB:          {2, GasFastestStep},
+	AND:          {2, GasFastestStep},
+	OR:           {2, GasFastestStep},
+	XOR:          {2, GasFastestStep},
+	NOT:          {1, GasFastestStep},
+	BYTE:         {2, GasFastestStep},
+	CALLDATALOAD: {1, GasFastestStep},
+	CALLDATACOPY: {3, GasFastestStep},
+	MLOAD:        {1, GasFastestStep},
+	MSTORE:       {2, GasFastestStep},
+	MSTORE8:      {2, GasFastestStep},
+	CODECOPY:     {3, GasFastestStep},
+	MUL:          {2, GasFastStep},
+	DIV:          {2, GasFastStep},
+	SDIV:         {2, GasFastStep},
+	MOD:          {2, GasFastStep},
+	SMOD:         {2, GasFastStep},
+	SIGNEXTEND:   {2, GasFastStep},
+	ADDMOD:       {3, GasMidStep},
+	MULMOD:       {3, GasMidStep},
+	JUMP:         {1, GasMidStep},
+	JUMPI:        {2, GasSlowStep},
+	EXP:          {2, GasSlowStep},
+	ADDRESS:      {0, GasQuickStep},
+	ORIGIN:       {0, GasQuickStep},
+	CALLER:       {0, GasQuickStep},
+	CALLVALUE:    {0, GasQuickStep},
+	CODESIZE:     {0, GasQuickStep},
+	GASPRICE:     {0, GasQuickStep},
+	COINBASE:     {0, GasQuickStep},
+	TIMESTAMP:    {0, GasQuickStep},
+	NUMBER:       {0, GasQuickStep},
+	DIFFICULTY:   {0, GasQuickStep},
+	GASLIMIT:     {0, GasQuickStep},
+	POP:          {0, GasQuickStep},
+	PC:           {0, GasQuickStep},
+	MSIZE:        {0, GasQuickStep},
+	GAS:          {0, GasQuickStep},
+	BLOCKHASH:    {1, GasExtStep},
+	BALANCE:      {0, GasExtStep},
+	EXTCODESIZE:  {1, GasExtStep},
+	EXTCODECOPY:  {4, GasExtStep},
+	SLOAD:        {1, GasStorageGet},
+	SSTORE:       {2, Zero},
+	SHA3:         {1, GasSha3Base},
+	CREATE:       {3, GasCreate},
+	CALL:         {7, GasCall},
+	CALLCODE:     {7, GasCall},
+	JUMPDEST:     {0, GasJumpDest},
+	SUICIDE:      {1, Zero},
+	RETURN:       {2, Zero},
+}
+
+func baseCheck(op OpCode, stack *Stack, gas *big.Int) {
+	if r, ok := _baseCheck[op]; ok {
+		stack.require(r.stack)
+
+		gas.Add(gas, r.gas)
 	}
+}
 
-	addStepGasUsage(GasStep)
+func toWordSize(size *big.Int) *big.Int {
+	tmp := new(big.Int)
+	tmp.Add(tmp, u256(31))
+	tmp.Div(tmp, u256(32))
+	return tmp
+}
+
+func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) {
+	var (
+		gas                 = new(big.Int)
+		newMemSize *big.Int = new(big.Int)
+	)
+	baseCheck(op, stack, gas)
 
-	var newMemSize *big.Int = ethutil.Big0
-	var additionalGas *big.Int = new(big.Int)
 	// Stack Check, memory resize & gas phase
 	switch op {
-	// Stack checks only
-	case ISZERO, CALLDATALOAD, POP, JUMP, NOT, EXTCODESIZE, BLOCKHASH: // 1
-		stack.require(1)
-	case JUMPI, ADD, SUB, DIV, MUL, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2
-		stack.require(2)
-	case ADDMOD, MULMOD: // 3
-		stack.require(3)
 	case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
 		n := int(op - SWAP1 + 2)
 		stack.require(n)
@@ -800,112 +870,83 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
 		n := int(op - LOG0)
 		stack.require(n + 2)
 
-		gas.Set(GasLog)
-		addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
-
 		mSize, mStart := stack.Peekn()
-		addStepGasUsage(mSize)
+
+		gas.Add(gas, GasLogBase)
+		gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), GasLogTopic))
+		gas.Add(gas, new(big.Int).Mul(mSize, GasLogData))
 
 		newMemSize = calcMemSize(mStart, mSize)
 	case EXP:
-		stack.require(2)
-
-		gas.Set(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()) + 1)))
-	// Gas only
-	case STOP:
-		gas.Set(ethutil.Big0)
-	case SUICIDE:
-		stack.require(1)
-
-		gas.Set(ethutil.Big0)
-	case SLOAD:
-		stack.require(1)
-
-		gas.Set(GasSLoad)
-	// Memory resize & Gas
+		gas.Add(gas, big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes())+1)))
 	case SSTORE:
 		stack.require(2)
 
-		var mult *big.Int
+		var g *big.Int
 		y, x := stack.Peekn()
 		val := statedb.GetState(context.Address(), x.Bytes())
 		if len(val) == 0 && len(y.Bytes()) > 0 {
 			// 0 => non 0
-			mult = ethutil.Big3
+			g = GasStorageAdd
 		} else if len(val) > 0 && len(y.Bytes()) == 0 {
-			statedb.Refund(self.env.Origin(), GasSStoreRefund)
+			statedb.Refund(self.env.Origin(), RefundStorage)
 
-			mult = ethutil.Big0
+			g = GasStorageMod
 		} else {
 			// non 0 => non 0 (or 0 => 0)
-			mult = ethutil.Big1
+			g = GasStorageMod
 		}
-		gas.Set(new(big.Int).Mul(mult, GasSStore))
-	case BALANCE:
-		stack.require(1)
-		gas.Set(GasBalance)
-	case MSTORE:
-		stack.require(2)
+		gas.Set(g)
 		newMemSize = calcMemSize(stack.Peek(), u256(32))
 	case MLOAD:
-		stack.require(1)
-
 		newMemSize = calcMemSize(stack.Peek(), u256(32))
 	case MSTORE8:
-		stack.require(2)
 		newMemSize = calcMemSize(stack.Peek(), u256(1))
 	case RETURN:
-		stack.require(2)
-
 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
 	case SHA3:
-		stack.require(2)
-		gas.Set(GasSha)
 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
-		additionalGas.Set(stack.data[stack.Len()-2])
-	case CALLDATACOPY:
-		stack.require(3)
 
+		words := toWordSize(stack.data[stack.Len()-2])
+		gas.Add(gas, words.Mul(words, GasSha3Word))
+	case CALLDATACOPY:
 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
-		additionalGas.Set(stack.data[stack.Len()-3])
-	case CODECOPY:
-		stack.require(3)
 
+		words := toWordSize(stack.data[stack.Len()-3])
+		gas.Add(gas, words.Mul(words, GasCopyWord))
+	case CODECOPY:
 		newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
-		additionalGas.Set(stack.data[stack.Len()-3])
-	case EXTCODECOPY:
-		stack.require(4)
 
+		words := toWordSize(stack.data[stack.Len()-3])
+		gas.Add(gas, words.Mul(words, GasCopyWord))
+	case EXTCODECOPY:
 		newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
-		additionalGas.Set(stack.data[stack.Len()-4])
+
+		words := toWordSize(stack.data[stack.Len()-4])
+		gas.Add(gas, words.Mul(words, GasCopyWord))
+	case CREATE:
+		size := new(big.Int).Set(stack.data[stack.Len()-2])
+		gas.Add(gas, size.Mul(size, GasCreateByte))
 	case CALL, CALLCODE:
-		stack.require(7)
-		gas.Set(GasCall)
-		addStepGasUsage(stack.data[stack.Len()-1])
+		gas.Add(gas, stack.data[stack.Len()-1])
+
+		if op == CALL {
+			if self.env.State().GetStateObject(stack.data[stack.Len()-2].Bytes()) == nil {
+				gas.Add(gas, GasCallNewAccount)
+			}
+
+			if len(stack.data[stack.Len()].Bytes()) > 0 {
+				gas.Add(gas, GasCallValueTransfer)
+			}
+		}
 
 		x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
 		y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
 
 		newMemSize = ethutil.BigMax(x, y)
-	case CREATE:
-		stack.require(3)
-		gas.Set(GasCreate)
-
 		newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
 	}
 
-	switch op {
-	case CALLDATACOPY, CODECOPY, EXTCODECOPY:
-		additionalGas.Add(additionalGas, u256(31))
-		additionalGas.Div(additionalGas, u256(32))
-		addStepGasUsage(additionalGas)
-	case SHA3:
-		additionalGas.Add(additionalGas, u256(31))
-		additionalGas.Div(additionalGas, u256(32))
-		additionalGas.Mul(additionalGas, GasSha3Byte)
-		addStepGasUsage(additionalGas)
-	}
-
 	if newMemSize.Cmp(ethutil.Big0) > 0 {
 		newMemSize.Add(newMemSize, u256(31))
 		newMemSize.Div(newMemSize, u256(32))
@@ -913,10 +954,10 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
 
 		if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
 			memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
-			memGasUsage.Mul(GasMemory, memGasUsage)
+			memGasUsage.Mul(GasMemWord, memGasUsage)
 			memGasUsage.Div(memGasUsage, u256(32))
 
-			addStepGasUsage(memGasUsage)
+			gas.Add(gas, memGasUsage)
 		}
 
 	}