An Ethereum compatible backend for Godwoken (a generic optimistic rollup framework). It includes generator and validator implementations.
Polyjuice provides an Ethereum compatible layer on Nervos CKB. It leverages account model as well as scalability provided by Godwoken, then integrates evmone as an EVM engine for running Ethereum smart contracts.
Polyjuice aims at 100% EVM compatibility as a goal, meaning we plan to support all smart contracts supported by the latest Ethereum hardfork version. See EVM-compatible.md and Addition-Features.md for more details.
- All Ethereum Virtual Machine Opcodes
- Value transfer
- pre-compiled contracts
- ecrecover
- sha256hash
- ripemd160hash
- dataCopy
- bigModExp
- bn256AddIstanbul
- bn256ScalarMulIstanbul
- bn256PairingIstanbul
- blake2F
header : [u8; 8] (header[0] = 0xff,
header[1] = 0xff,
header[2] = 0xff,
header[3..7] = "POLY"
header[7] = call_kind { 0: CALL, 3: CREATE })
gas_limit : u64 (little endian)
gas_price : u128 (little endian)
value : u128 (little endian)
input_size : u32 (little endian)
input_data : [u8; input_size] (input data)
to_address : [u8; 20] (optional) the `to` address of a native transfer transaction
Every Polyjuice argument fields must be serialized one by one and put into Godwoken RawL2Transaction.args
for Polyjuice to read. When the input_data
contains 56 bytes, for contract call, the serialized data size is 8 + 8 + 16 + 16 + 4 + 56 = 108
bytes; for native token transfer, the serialized data size is 8 + 8 + 16 + 16 + 4 + 56 + 20 = 128
bytes.
code_hash: Polyjuice_validator_type_script_hash
hash_type: type
args:
rollup_type_hash : [u8; 32]
sudt_id : u32 (little endian, the token id)
eth_addr_reg_id : u32 (little endian, the ETH_Address_Registry Contract id)
Polyjuice creator account is a Godwoken account for creating Polyjuice contract account. This account can only be created by meta contract, and the account id is used as the chain id in Polyjuice. The sudt_id
field in script args is the sUDT token current Polyjuice instance bind to as pCKB
. The eth_addr_reg_id
field in script args is the id of ETH Address Registry
layer2 contract which provides two-ways mappings between eth_address
and gw_script_hash
.
code_hash: polyjuice_validator_type_script_hash
hash_type: type
args:
rollup_type_hash : [u8; 32] (the rollup type hash of the current Godwoken deployment)
creator_account_id : u32 (little endian, it's the ID of Polyjuice Root Account)
contract_address : [u8; 20] (this 20 bytes value is keccak256(info_data)[12..], and the
`info_data` to be hashed depends on how the account was
created: `CREATE` or `CREATE2`)
The contract_address
could be calculated through 2 ways:
The Polyjuice contract account created in Polyjuice by CREATE
call kind or Opcode.
info_content:
sender_address : [u8; 20] (the sender's eth_address)
sender_nonce : u32 (the transaction counter of the sender account)
info_data: rlp_encode(sender_address, sender_nonce)
The Polyjuice contract account created in Polyjuice by CREATE2
Opcode.
info_data:
special_byte : u8 (value is '0xff', refer to Ethereum)
sender_address : [u8; 20] (the sender's eth_address)
create2_salt : [u8; 32] (create2 salt)
init_code_hash : [u8; 32] (keccak256(init_code))
Polyjuice only provides contract accounts. Godwoken's user account is leveraged to act as externally owned account (EOA). In the latest version of Polyjuice, the EOA address is native eth_address
, which is the rightmost 160 bits of a Keccak hash of an ECDSA public key.
cargo install moleculec --version 0.7.2
git submodule update --init --recursive --depth=1
make dist
cd polyjuice-tests
cargo test --lib # unit test
cargo test --test ethereum_test -- ethereum_test