Skip to content
This repository has been archived by the owner on Nov 18, 2022. It is now read-only.

Create new account during transferring if the to_address is not registered. #177

Merged
merged 7 commits into from Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 77 additions & 5 deletions c/polyjuice.h
Expand Up @@ -1020,8 +1020,37 @@ int handle_transfer(gw_context_t* ctx,
return 0;
}

int load_eth_eoa_type_hash(gw_context_t* ctx, uint8_t eoa_type_hash[GW_KEY_BYTES]) {
mol_seg_t rollup_config_seg;
rollup_config_seg.ptr = ctx->rollup_config;
rollup_config_seg.size = ctx->rollup_config_size;

mol_seg_t allowed_eoa_list_seg =
MolReader_RollupConfig_get_allowed_eoa_type_hashes(&rollup_config_seg);
uint32_t len = MolReader_AllowedTypeHashVec_length(&allowed_eoa_list_seg);
for (uint32_t i = 0; i < len; i++) {
mol_seg_res_t allowed_type_hash_res =
MolReader_AllowedTypeHashVec_get(&allowed_eoa_list_seg, i);

if (!is_errno_ok(&allowed_type_hash_res)) {
return GW_FATAL_INVALID_DATA;
}
mol_seg_t type_seg =
MolReader_AllowedTypeHash_get_type_(&allowed_type_hash_res.seg);
if (*(uint8_t *)type_seg.ptr == GW_ALLOWED_EOA_ETH) {
mol_seg_t eth_lock_code_hash_seg =
MolReader_AllowedTypeHash_get_hash(&allowed_type_hash_res.seg);
memcpy(eoa_type_hash, eth_lock_code_hash_seg.ptr, 32);
return 0;
}
}
ckb_debug("Cannot find EoA type hash of ETH.");
return FATAL_POLYJUICE;
}

int handle_native_token_transfer(gw_context_t* ctx, uint32_t from_id,
uint256_t value, gw_reg_addr_t* from_addr) {
uint256_t value, gw_reg_addr_t* from_addr,
uint64_t* gas_used) {
if (g_creator_account_id == UINT32_MAX) {
ckb_debug("[handle_native_token_transfer] g_creator_account_id wasn't set.");
return ERROR_NATIVE_TOKEN_TRANSFER;
Expand Down Expand Up @@ -1066,7 +1095,48 @@ int handle_native_token_transfer(gw_context_t* ctx, uint32_t from_id,
ckb_debug("[handle_native_token_transfer] to_address is a contract");
return ERROR_NATIVE_TOKEN_TRANSFER;
}
} else if (ret != GW_ERROR_NOT_FOUND && ret != 0) {
} else if (ret == GW_ERROR_NOT_FOUND) {
ckb_debug("[handle_native_token_transfer] create new EoA account");
//build eoa script
uint8_t eoa_type_hash[GW_KEY_BYTES] = {0};
ret = load_eth_eoa_type_hash(ctx, eoa_type_hash);
if (ret != 0) {
return ret;
}
// EOA script args len: 32 + 20
int eoa_script_args_len = 32 + 20;
uint8_t script_args[eoa_script_args_len];
memcpy(script_args, g_rollup_script_hash, 32);
memcpy(script_args + 32, g_eoa_transfer_to_address.bytes, 20);
mol_seg_t new_script_seg;
ret = build_script(eoa_type_hash, g_script_hash_type, script_args,
eoa_script_args_len, &new_script_seg);
if (ret != 0) {
return ret;
}
uint32_t new_account_id;
ret = ctx->sys_create(ctx, new_script_seg.ptr, new_script_seg.size,
&new_account_id);
if (ret != 0) {
ckb_debug("[handle_native_token_transfer] create new account failed.");
return ret;
}
Flouse marked this conversation as resolved.
Show resolved Hide resolved
uint8_t account_script_hash[32] = {0};
ret = ctx->sys_get_script_hash_by_account_id(ctx, new_account_id,
account_script_hash);
if (ret != 0) {
ckb_debug("[handle_native_token_transfer] failed to get created eth account script hash");
return ret;
}

ret = gw_register_eth_address(ctx, account_script_hash);
if (ret != 0) {
ckb_debug("[handle_native_token_transfer] failed to register eth address");
return ret;
}
// charge gas for new account
*gas_used += NEW_ACCOUNT_GAS;
} else {
return ret;
}

Expand Down Expand Up @@ -1484,14 +1554,16 @@ int run_polyjuice() {
for (int i = 0; i < 32; i++) {
value_ptr[i] = msg.value.bytes[31 - i];
}

uint64_t gas_used = min_gas;
gw_reg_addr_t from_addr = {0};
// handle error later
int transfer_ret = handle_native_token_transfer(&context, context.transaction_context.from_id,
value, &from_addr);
value, &from_addr, &gas_used);
ckb_debug("END handle_native_token_transfer");
// handle fee
uint256_t gas_fee = calculate_fee(g_gas_price, min_gas);
debug_print_int("[handle_native_token_transfer] gas_used", min_gas);
uint256_t gas_fee = calculate_fee(g_gas_price, gas_used);
debug_print_int("[handle_native_token_transfer] gas_used", gas_used);
ret = sudt_pay_fee(&context, g_sudt_id, from_addr, gas_fee);
// handle native token transfer error
if (ret != 0) {
Expand Down
2 changes: 2 additions & 0 deletions c/polyjuice_globals.h
Expand Up @@ -55,5 +55,7 @@ static evmc_address g_eoa_transfer_to_address = {0};
#define DATA_NONE_ZERO_TX_GAS 16
/* Gas per byte of data attached to a transaction */
#define DATA_ZERO_TX_GAS 4
/* Gas of new account creation*/
#define NEW_ACCOUNT_GAS 25000

#endif // POLYJUICE_GLOBALS_H