@ -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 )
}