Skip to content
This repository has been archived by the owner on Mar 8, 2024. It is now read-only.

Update precompile addresses to be QIP2 compatible #72

Merged
merged 2 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion common/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Address struct {
inner AddressData
}

type AddressBytes [20]byte
type AddressBytes [AddressLength]byte

type AddressData interface {
Bytes() []byte
Expand Down Expand Up @@ -257,6 +257,19 @@ func HexToAddress(s string, nodeLocation Location) Address {
return BytesToAddress(FromHex(s), nodeLocation)
}

func HexToAddressBytes(s string) AddressBytes {
var a AddressBytes
a.SetBytes(FromHex(s))
return a
}

func (a *AddressBytes) SetBytes(b []byte) {
if len(b) > len(a) {
b = b[len(b)-AddressLength:]
}
copy(a[AddressLength-len(b):], b)
}

// IsHexAddress verifies whether a string can represent a valid hex-encoded
// Quai address or not.
func IsHexAddress(s string) bool {
Expand Down
3 changes: 3 additions & 0 deletions common/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ func TestHash_Format(t *testing.T) {
}

func TestZeroAddress(t *testing.T) {
t.Log(fmt.Sprintf("0x%x00000000000000000000000000000000000000", nodeLocation.BytePrefix()))
addr := HexToAddress("0x110000000000000000000000000000000000115", nodeLocation)
t.Log(fmt.Sprintf("0x%x000000000000000000000000000000000000%02x", nodeLocation.BytePrefix(), addr.Bytes20()[19]))
t.Log(ZeroAddress(nodeLocation).String())
internal, err := ZeroAddress(nodeLocation).InternalAddress()
if err != nil {
Expand Down
134 changes: 10 additions & 124 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
"math/big"

"github.com/dominant-strategies/go-quai/common"
Expand All @@ -41,136 +42,21 @@ type PrecompiledContract interface {
Run(input []byte) ([]byte, error) // Run runs the precompiled contract
}

var TranslatedAddresses = map[common.AddressBytes]int{
common.AddressBytes(intToByteArray20(1)): 0,
common.AddressBytes(intToByteArray20(2)): 1,
common.AddressBytes(intToByteArray20(3)): 2,
common.AddressBytes(intToByteArray20(4)): 3,
common.AddressBytes(intToByteArray20(5)): 4,
common.AddressBytes(intToByteArray20(6)): 5,
common.AddressBytes(intToByteArray20(7)): 6,
common.AddressBytes(intToByteArray20(8)): 7,
common.AddressBytes(intToByteArray20(9)): 8,
}

var (
PrecompiledContracts map[common.AddressBytes]PrecompiledContract = make(map[common.AddressBytes]PrecompiledContract)
PrecompiledAddresses map[string][]common.Address = make(map[string][]common.Address)
)

func InitializePrecompiles(nodeLocation common.Location) {
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][0].Bytes20()] = &ecrecover{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][1].Bytes20()] = &sha256hash{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][2].Bytes20()] = &ripemd160hash{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][3].Bytes20()] = &dataCopy{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][4].Bytes20()] = &bigModExp{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][5].Bytes20()] = &bn256Add{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][6].Bytes20()] = &bn256ScalarMul{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][7].Bytes20()] = &bn256Pairing{}
PrecompiledContracts[PrecompiledAddresses[nodeLocation.Name()][8].Bytes20()] = &blake2F{}
}

func init() {

PrecompiledAddresses["cyprus1"] = []common.Address{
common.HexToAddress("0x1400000000000000000000000000000000000001", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000002", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000003", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000004", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000005", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000006", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000007", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000008", common.Location{0, 0}),
common.HexToAddress("0x1400000000000000000000000000000000000009", common.Location{0, 0}),
}
PrecompiledAddresses["cyprus2"] = []common.Address{
common.HexToAddress("0x2000000000000000000000000000000000000001", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000002", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000003", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000004", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000005", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000006", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000007", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000008", common.Location{0, 1}),
common.HexToAddress("0x2000000000000000000000000000000000000009", common.Location{0, 1}),
}
PrecompiledAddresses["cyprus3"] = []common.Address{
common.HexToAddress("0x3E00000000000000000000000000000000000001", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000002", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000003", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000004", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000005", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000006", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000007", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000008", common.Location{0, 2}),
common.HexToAddress("0x3E00000000000000000000000000000000000009", common.Location{0, 2}),
}
PrecompiledAddresses["paxos1"] = []common.Address{
common.HexToAddress("0x5A00000000000000000000000000000000000001", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000002", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000003", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000004", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000005", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000006", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000007", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000008", common.Location{1, 0}),
common.HexToAddress("0x5A00000000000000000000000000000000000009", common.Location{1, 0}),
}
PrecompiledAddresses["paxos2"] = []common.Address{
common.HexToAddress("0x7800000000000000000000000000000000000001", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000002", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000003", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000004", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000005", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000006", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000007", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000008", common.Location{1, 1}),
common.HexToAddress("0x7800000000000000000000000000000000000009", common.Location{1, 1}),
}
PrecompiledAddresses["paxos3"] = []common.Address{
common.HexToAddress("0x9600000000000000000000000000000000000001", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000002", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000003", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000004", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000005", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000006", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000007", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000008", common.Location{1, 2}),
common.HexToAddress("0x9600000000000000000000000000000000000009", common.Location{1, 2}),
}
PrecompiledAddresses["hydra1"] = []common.Address{
common.HexToAddress("0xB400000000000000000000000000000000000001", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000002", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000003", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000004", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000005", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000006", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000007", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000008", common.Location{2, 0}),
common.HexToAddress("0xB400000000000000000000000000000000000009", common.Location{2, 0}),
}
PrecompiledAddresses["hydra2"] = []common.Address{
common.HexToAddress("0xD200000000000000000000000000000000000001", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000002", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000003", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000004", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000005", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000006", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000007", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000008", common.Location{2, 1}),
common.HexToAddress("0xD200000000000000000000000000000000000009", common.Location{2, 1}),
}
PrecompiledAddresses["hydra3"] = []common.Address{
common.HexToAddress("0xF000000000000000000000000000000000000001", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000002", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000003", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000004", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000005", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000006", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000007", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000008", common.Location{2, 2}),
common.HexToAddress("0xF000000000000000000000000000000000000009", common.Location{2, 2}),
}
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000001", nodeLocation.BytePrefix()))] = &ecrecover{}
wizeguyy marked this conversation as resolved.
Show resolved Hide resolved
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000002", nodeLocation.BytePrefix()))] = &sha256hash{}
jdowning100 marked this conversation as resolved.
Show resolved Hide resolved
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000003", nodeLocation.BytePrefix()))] = &ripemd160hash{}
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000004", nodeLocation.BytePrefix()))] = &dataCopy{}
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000005", nodeLocation.BytePrefix()))] = &bigModExp{}
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000006", nodeLocation.BytePrefix()))] = &bn256Add{}
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000007", nodeLocation.BytePrefix()))] = &bn256ScalarMul{}
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000008", nodeLocation.BytePrefix()))] = &bn256Pairing{}
PrecompiledContracts[common.HexToAddressBytes(fmt.Sprintf("0x%x00000000000000000000000000000000000009", nodeLocation.BytePrefix()))] = &blake2F{}
}

// ActivePrecompiles returns the precompiles enabled with the current configuration.
Expand Down
12 changes: 9 additions & 3 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ type (
)

func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool, common.Address) {
if index, ok := TranslatedAddresses[addr.Bytes20()]; ok {
addr = PrecompiledAddresses[evm.chainConfig.Location.Name()][index]
}
p, ok := PrecompiledContracts[addr.Bytes20()]
if !ok {
// to translate the address, we add the last byte of the address to the location-specific zero address
// to support more than 255 precompiles, we could use the last two bytes, but it's likely unnecessary
translatedAddress := common.HexToAddressBytes(fmt.Sprintf("0x%x000000000000000000000000000000000000%02x", evm.chainConfig.Location.BytePrefix(), addr.Bytes20()[19]))
p, ok = PrecompiledContracts[translatedAddress]
if ok {
addr = common.Bytes20ToAddress(translatedAddress, evm.chainConfig.Location)
}
}
return p, ok, addr
}

Expand Down
Loading