public static byte[] generateCreate2ContractAddress(
            byte[] address, byte[] salt, byte[] initCode) {
        if (address.length != ADDRESS_BYTE_SIZE) {
            throw new RuntimeException("Invalid address size");
        }
        if (salt.length != SALT_SIZE) {
            throw new RuntimeException("Invalid salt size");
        }
        byte[] hashedInitCode = Hash.sha3(initCode);
        byte[] buffer = new byte[1 + address.length + salt.length + hashedInitCode.length];

        buffer[0] = (byte) 0xff;
        int offset = 1;
        System.arraycopy(address, 0, buffer, offset, address.length);
        offset += address.length;
        System.arraycopy(salt, 0, buffer, offset, salt.length);
        offset += salt.length;
        System.arraycopy(hashedInitCode, 0, buffer, offset, hashedInitCode.length);

        byte[] hashed = Hash.sha3(buffer);
        return Arrays.copyOfRange(hashed, 12, hashed.length);
    }
@Test
    public void testEIP1014Create2ContractAddress() {
        // https://eips.ethereum.org/EIPS/eip-1014
        // example 0
        assertEquals(
                Keys.toChecksumAddress(
                        generateCreate2ContractAddress(
                                "0x0000000000000000000000000000000000000000",
                                hexStringToByteArray(
                                        "0x0000000000000000000000000000000000000000000000000000000000000000"),
                                hexStringToByteArray("0x00"))),
                ("0x4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38"));

        // example 1
        assertEquals(
                Keys.toChecksumAddress(
                        generateCreate2ContractAddress(
                                "0xdeadbeef00000000000000000000000000000000",
                                hexStringToByteArray(
                                        "0x0000000000000000000000000000000000000000000000000000000000000000"),
                                hexStringToByteArray("0x00"))),
                ("0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3"));

        // example 2
        assertEquals(
                Keys.toChecksumAddress(
                        generateCreate2ContractAddress(
                                "0xdeadbeef00000000000000000000000000000000",
                                hexStringToByteArray(
                                        "0x000000000000000000000000feed000000000000000000000000000000000000"),
                                hexStringToByteArray("0x00"))),
                ("0xD04116cDd17beBE565EB2422F2497E06cC1C9833"));

        // example 3
        assertEquals(
                Keys.toChecksumAddress(
                        generateCreate2ContractAddress(
                                "0x0000000000000000000000000000000000000000",
                                hexStringToByteArray(
                                        "0x0000000000000000000000000000000000000000000000000000000000000000"),
                                hexStringToByteArray("0xdeadbeef"))),
                ("0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e"));

        // example 4
        assertEquals(
                Keys.toChecksumAddress(
                        generateCreate2ContractAddress(
                                "0x00000000000000000000000000000000deadbeef",
                                hexStringToByteArray(
                                        "0x00000000000000000000000000000000000000000000000000000000cafebabe"),
                                hexStringToByteArray("0xdeadbeef"))),
                ("0x60f3f640a8508fC6a86d45DF051962668E1e8AC7"));

        // example 5
        assertEquals(
                Keys.toChecksumAddress(
                        generateCreate2ContractAddress(
                                "0x00000000000000000000000000000000deadbeef",
                                hexStringToByteArray(
                                        "0x00000000000000000000000000000000000000000000000000000000cafebabe"),
                                hexStringToByteArray(
                                        "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))),
                ("0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C"));

        // example 6
        assertEquals(
                Keys.toChecksumAddress(
                        generateCreate2ContractAddress(
                                "0x0000000000000000000000000000000000000000",
                                hexStringToByteArray(
                                        "0x0000000000000000000000000000000000000000000000000000000000000000"),
                                hexStringToByteArray("0x"))),
                ("0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0"));
    }