aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm')
-rw-r--r--core/vm/contracts.go125
-rw-r--r--core/vm/evm.go6
2 files changed, 105 insertions, 26 deletions
diff --git a/core/vm/contracts.go b/core/vm/contracts.go
index 20b741f8f..0e4fe0198 100644
--- a/core/vm/contracts.go
+++ b/core/vm/contracts.go
@@ -54,9 +54,22 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
common.BytesToAddress([]byte{3}): &ripemd160hash{},
common.BytesToAddress([]byte{4}): &dataCopy{},
common.BytesToAddress([]byte{5}): &bigModExp{},
- common.BytesToAddress([]byte{6}): &bn256Add{},
- common.BytesToAddress([]byte{7}): &bn256ScalarMul{},
- common.BytesToAddress([]byte{8}): &bn256Pairing{},
+ common.BytesToAddress([]byte{6}): &bn256AddByzantium{},
+ common.BytesToAddress([]byte{7}): &bn256ScalarMulByzantium{},
+ common.BytesToAddress([]byte{8}): &bn256PairingByzantium{},
+}
+
+// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum
+// contracts used in the Istanbul release.
+var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
+ common.BytesToAddress([]byte{1}): &ecrecover{},
+ common.BytesToAddress([]byte{2}): &sha256hash{},
+ common.BytesToAddress([]byte{3}): &ripemd160hash{},
+ common.BytesToAddress([]byte{4}): &dataCopy{},
+ common.BytesToAddress([]byte{5}): &bigModExp{},
+ common.BytesToAddress([]byte{6}): &bn256AddIstanbul{},
+ common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
+ common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
}
// RunPrecompiledContract runs and evaluates the output of a precompiled contract.
@@ -271,15 +284,9 @@ func newTwistPoint(blob []byte) (*bn256.G2, error) {
return p, nil
}
-// bn256Add implements a native elliptic curve point addition.
-type bn256Add struct{}
-
-// RequiredGas returns the gas required to execute the pre-compiled contract.
-func (c *bn256Add) RequiredGas(input []byte) uint64 {
- return params.Bn256AddGas
-}
-
-func (c *bn256Add) Run(input []byte) ([]byte, error) {
+// runBn256Add implements the Bn256Add precompile, referenced by both
+// Byzantium and Istanbul operations.
+func runBn256Add(input []byte) ([]byte, error) {
x, err := newCurvePoint(getData(input, 0, 64))
if err != nil {
return nil, err
@@ -293,15 +300,35 @@ func (c *bn256Add) Run(input []byte) ([]byte, error) {
return res.Marshal(), nil
}
-// bn256ScalarMul implements a native elliptic curve scalar multiplication.
-type bn256ScalarMul struct{}
+// bn256Add implements a native elliptic curve point addition conforming to
+// Istanbul consensus rules.
+type bn256AddIstanbul struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 {
+ return params.Bn256AddGasIstanbul
+}
+
+func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) {
+ return runBn256Add(input)
+}
+
+// bn256AddByzantium implements a native elliptic curve point addition
+// conforming to Byzantium consensus rules.
+type bn256AddByzantium struct{}
// RequiredGas returns the gas required to execute the pre-compiled contract.
-func (c *bn256ScalarMul) RequiredGas(input []byte) uint64 {
- return params.Bn256ScalarMulGas
+func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 {
+ return params.Bn256AddGasByzantium
+}
+
+func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) {
+ return runBn256Add(input)
}
-func (c *bn256ScalarMul) Run(input []byte) ([]byte, error) {
+// runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by
+// both Byzantium and Istanbul operations.
+func runBn256ScalarMul(input []byte) ([]byte, error) {
p, err := newCurvePoint(getData(input, 0, 64))
if err != nil {
return nil, err
@@ -311,6 +338,32 @@ func (c *bn256ScalarMul) Run(input []byte) ([]byte, error) {
return res.Marshal(), nil
}
+// bn256ScalarMulIstanbul implements a native elliptic curve scalar
+// multiplication conforming to Istanbul consensus rules.
+type bn256ScalarMulIstanbul struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 {
+ return params.Bn256ScalarMulGasIstanbul
+}
+
+func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) {
+ return runBn256ScalarMul(input)
+}
+
+// bn256ScalarMulByzantium implements a native elliptic curve scalar
+// multiplication conforming to Byzantium consensus rules.
+type bn256ScalarMulByzantium struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 {
+ return params.Bn256ScalarMulGasByzantium
+}
+
+func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) {
+ return runBn256ScalarMul(input)
+}
+
var (
// true32Byte is returned if the bn256 pairing check succeeds.
true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
@@ -322,15 +375,9 @@ var (
errBadPairingInput = errors.New("bad elliptic curve pairing size")
)
-// bn256Pairing implements a pairing pre-compile for the bn256 curve
-type bn256Pairing struct{}
-
-// RequiredGas returns the gas required to execute the pre-compiled contract.
-func (c *bn256Pairing) RequiredGas(input []byte) uint64 {
- return params.Bn256PairingBaseGas + uint64(len(input)/192)*params.Bn256PairingPerPointGas
-}
-
-func (c *bn256Pairing) Run(input []byte) ([]byte, error) {
+// runBn256Pairing implements the Bn256Pairing precompile, referenced by both
+// Byzantium and Istanbul operations.
+func runBn256Pairing(input []byte) ([]byte, error) {
// Handle some corner cases cheaply
if len(input)%192 > 0 {
return nil, errBadPairingInput
@@ -358,3 +405,29 @@ func (c *bn256Pairing) Run(input []byte) ([]byte, error) {
}
return false32Byte, nil
}
+
+// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve
+// conforming to Istanbul consensus rules.
+type bn256PairingIstanbul struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 {
+ return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul
+}
+
+func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) {
+ return runBn256Pairing(input)
+}
+
+// bn256PairingByzantium implements a pairing pre-compile for the bn256 curve
+// conforming to Byzantium consensus rules.
+type bn256PairingByzantium struct{}
+
+// RequiredGas returns the gas required to execute the pre-compiled contract.
+func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 {
+ return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium
+}
+
+func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
+ return runBn256Pairing(input)
+}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 030f0c789..98d9e31fb 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -47,6 +47,9 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
if evm.chainRules.IsByzantium {
precompiles = PrecompiledContractsByzantium
}
+ if evm.chainRules.IsIstanbul {
+ precompiles = PrecompiledContractsIstanbul
+ }
if p := precompiles[*contract.CodeAddr]; p != nil {
return RunPrecompiledContract(p, input, contract)
}
@@ -206,6 +209,9 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if evm.chainRules.IsByzantium {
precompiles = PrecompiledContractsByzantium
}
+ if evm.chainRules.IsIstanbul {
+ precompiles = PrecompiledContractsIstanbul
+ }
if precompiles[addr] == nil && evm.chainRules.IsEIP158 && value.Sign() == 0 {
// Calling a non existing account, don't do anything, but ping the tracer
if evm.vmConfig.Debug && evm.depth == 0 {