CREATE address RLP codec¶
The CREATE and CREATE2 address rules (YP §7, EIP-1014).
function create_address¶
The CREATE address (YP §7): the low 20 bytes of
keccak256(rlp([sender, nonce])).
function create_address(sender : address, nonce : account_nonce) -> address = {
let address_length = rlp_addr_size();
let nonce_length = rlp_uint_word_size(nonce);
let content_len = address_length + nonce_length;
let encoded_len = rlp_list_size(content_len);
let encoder = rlp_encoder_begin(encoded_len);
rlp_write_list_prefix(content_len);
rlp_write_addr(sender);
rlp_write_uint(nonce);
let encoded = rlp_encoder_finish(encoder);
let digest = keccak256(encoded);
let digest_word = hash_to_word(digest);
let address = word_to_address(digest_word);
rlp_encoder_rewind(encoder);
address
}Interprets a digest as the corresponding big-endian EVM word.
function hash_to_word(bytes : hash) -> word =
unsigned(
bytes[0]
@ bytes[1]
@ bytes[2]
@ bytes[3]
@ bytes[4]
@ bytes[5]
@ bytes[6]
@ bytes[7]
@ bytes[8]
@ bytes[9]
@ bytes[10]
@ bytes[11]
@ bytes[12]
@ bytes[13]
@ bytes[14]
@ bytes[15]
@ bytes[16]
@ bytes[17]
@ bytes[18]
@ bytes[19]
@ bytes[20]
@ bytes[21]
@ bytes[22]
@ bytes[23]
@ bytes[24]
@ bytes[25]
@ bytes[26]
@ bytes[27]
@ bytes[28]
@ bytes[29]
@ bytes[30]
@ bytes[31],
)function rlp_addr_size() -> int(21) = RLP_ENCODED_ADDRESS_LENGTHfunction rlp_encoder_begin(expected_len) =
struct { start = scratch_reserve(expected_len), expected_len = expected_len }Finishes an exact-size construction and retains its encoded bytes.
function rlp_encoder_finish(encoder : RlpEncoder) -> ScratchSlice = {
let encoded = scratch_finish(encoder.start);
assert(encoded.len == encoder.expected_len, "RLP encoder length");
encoded
}Releases every byte appended by an encoder after its result is consumed.
function rlp_encoder_rewind(encoder : RlpEncoder) -> unit =
scratch_rewind(encoder.start)function rlp_list_size(content_len) = {
rlp_length_prefix_len(content_len) + content_len
}function rlp_uint_word_size(w) = {
let len = rlp_minimal_word_len(w);
let first =
if len == 1 then word_low_byte(w) else 0x00;
if (len == 1) & (first[7] == bitzero) then {
1
} else {
1 + len
}
}Appends one Ethereum address as an RLP byte string.
function rlp_write_addr(a : address) -> unit = {
rlp_write_string_prefix(ADDRESS_BYTE_LENGTH, a[0]);
scratch_push_address(a)
}function rlp_write_list_prefix(content_len) = {
if content_len <= RLP_SHORT_LENGTH_LIMIT then {
let length_byte = rlp_length_byte(content_len);
let prefix = add_bits(0xc0, length_byte);
scratch_push_byte(prefix)
} else {
let length_word = rlp_length_word(content_len);
let length_len = rlp_minimal_word_len(length_word);
let length_byte = rlp_length_byte(length_len);
let prefix = add_bits(0xf7, length_byte);
scratch_push_byte(prefix);
scratch_push_word_be(length_word, length_len)
}
}Converts a word to its low 160-bit address in canonical byte order.
function word_to_address(value : word) -> address = {
let zero_bytes = vector_init(20, 0x00);
var result : address = Address(zero_bytes);
result[0] = get_slice_int(8, value, 152);
result[1] = get_slice_int(8, value, 144);
result[2] = get_slice_int(8, value, 136);
result[3] = get_slice_int(8, value, 128);
result[4] = get_slice_int(8, value, 120);
result[5] = get_slice_int(8, value, 112);
result[6] = get_slice_int(8, value, 104);
result[7] = get_slice_int(8, value, 96);
result[8] = get_slice_int(8, value, 88);
result[9] = get_slice_int(8, value, 80);
result[10] = get_slice_int(8, value, 72);
result[11] = get_slice_int(8, value, 64);
result[12] = get_slice_int(8, value, 56);
result[13] = get_slice_int(8, value, 48);
result[14] = get_slice_int(8, value, 40);
result[15] = get_slice_int(8, value, 32);
result[16] = get_slice_int(8, value, 24);
result[17] = get_slice_int(8, value, 16);
result[18] = get_slice_int(8, value, 8);
result[19] = get_slice_int(8, value, 0);
result
}An account transaction-count nonce (EIP-2681).
type account_nonce = range(0, account_nonce_bound)A 20-byte account address (YP §4.1), in canonical protocol byte order.
type address = vector(20, inc, byte)