This repository was archived by the owner on Nov 9, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy patheth_addr_reg.c
More file actions
162 lines (143 loc) · 4.99 KB
/
eth_addr_reg.c
File metadata and controls
162 lines (143 loc) · 4.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/**
* `ETH Address Registry` layer2 contract
*
* This contract introduces two-ways mappings between `eth_address` and
* `gw_script_hash`.
*
* - `eth_address` is the address of an Ethereum EOA (externally owned account
* ) or a Polyjuice contract account.
*
* - Godwoken account script hash(a.k.a. `gw_script_hash`) is a key used for
* locating the account lock. Godwoken enforces one-to-one mapping between
* layer 2 lock script and accountID.
*/
#include "gw_eth_addr_reg.h"
#include "sudt_utils.h"
/* MSG_TYPE */
#define MSG_QUERY_GW_BY_ETH 0
#define MSG_QUERY_ETH_BY_GW 1
#define MSG_SET_MAPPING 2
#define MSG_BATCH_SET_MAPPING 3
int handle_fee(gw_context_t *ctx, uint32_t registry_id, uint256_t amount) {
if (ctx == NULL) {
return GW_FATAL_INVALID_CONTEXT;
}
/* payer's registry address */
uint8_t payer_script_hash[32] = {0};
int ret = ctx->sys_get_script_hash_by_account_id(
ctx, ctx->transaction_context.from_id, payer_script_hash);
if (ret != 0) {
return ret;
}
gw_reg_addr_t payer_addr;
ret = ctx->sys_get_registry_address_by_script_hash(ctx, payer_script_hash,
registry_id, &payer_addr);
if (ret != 0) {
return ret;
}
return sudt_pay_fee(ctx, CKB_SUDT_ACCOUNT_ID, payer_addr, amount);
}
int main() {
ckb_debug("====== ETH Address Registry ======");
/* initialize context */
gw_context_t ctx = {0};
int ret = gw_context_init(&ctx);
if (ret != 0) {
return ret;
};
/* verify and parse args */
mol_seg_t args_seg;
args_seg.ptr = ctx.transaction_context.args;
args_seg.size = ctx.transaction_context.args_len;
if (MolReader_ETHAddrRegArgs_verify(&args_seg, false) != MOL_OK) {
return GW_FATAL_INVALID_DATA;
}
mol_union_t msg = MolReader_ETHAddrRegArgs_unpack(&args_seg);
/* handle message */
if (msg.item_id == MSG_QUERY_GW_BY_ETH) {
mol_seg_t eth_address_seg = MolReader_EthToGw_get_eth_address(&msg.seg);
uint8_t script_hash[GW_VALUE_BYTES] = {0};
/* addr */
gw_reg_addr_t addr;
memcpy(addr.addr, eth_address_seg.ptr, 20);
addr.addr_len = 20;
addr.reg_id = ctx.transaction_context.to_id;
/* get script hash */
ret = ctx.sys_get_script_hash_by_registry_address(&ctx, &addr, script_hash);
if (ret != 0) {
return ret;
}
ret = ctx.sys_set_program_return_data(&ctx, script_hash, GW_VALUE_BYTES);
if (ret != 0) {
return ret;
}
} else if (msg.item_id == MSG_QUERY_ETH_BY_GW) {
mol_seg_t script_hash_seg = MolReader_GwToEth_get_gw_script_hash(&msg.seg);
gw_reg_addr_t addr;
ret = ctx.sys_get_registry_address_by_script_hash(
&ctx, script_hash_seg.ptr, ctx.transaction_context.to_id, &addr);
if (ret != 0) {
return ret;
}
if (addr.addr_len != GW_ETH_ADDRESS_LEN) {
return GW_FATAL_INVALID_DATA;
}
ret = ctx.sys_set_program_return_data(&ctx, addr.addr, GW_ETH_ADDRESS_LEN);
if (ret != 0) {
return ret;
}
} else if (msg.item_id == MSG_SET_MAPPING) {
mol_seg_t script_hash_seg =
MolReader_SetMapping_get_gw_script_hash(&msg.seg);
ret = gw_register_eth_address(&ctx, script_hash_seg.ptr);
if (ret != 0) {
return ret;
}
/* charge fee */
mol_seg_t fee_seg = MolReader_SetMapping_get_fee(&msg.seg);
mol_seg_t amount_seg = MolReader_Fee_get_amount(&fee_seg);
mol_seg_t reg_id_seg = MolReader_Fee_get_registry_id(&fee_seg);
uint32_t reg_id = 0;
_gw_fast_memcpy((uint8_t *)(®_id), reg_id_seg.ptr, sizeof(uint32_t));
uint256_t fee_amount = {0};
_gw_fast_memcpy((uint8_t *)(&fee_amount), (uint8_t *)amount_seg.ptr,
sizeof(uint128_t));
ret = handle_fee(&ctx, reg_id, fee_amount);
if (ret != 0) {
return ret;
}
} else if (msg.item_id == MSG_BATCH_SET_MAPPING) {
mol_seg_t script_hashes_seg =
MolReader_BatchSetMapping_get_gw_script_hashes(&msg.seg);
uint32_t script_hashes_size =
MolReader_Byte32Vec_length(&script_hashes_seg);
for (uint32_t i = 0; i < script_hashes_size; i++) {
mol_seg_res_t script_hash_res =
MolReader_Byte32Vec_get(&script_hashes_seg, i);
if (script_hash_res.errno != MOL_OK) {
ckb_debug("invalid script hash");
return GW_FATAL_INVALID_DATA;
}
ret = gw_register_eth_address(&ctx, script_hash_res.seg.ptr);
if (ret != 0) {
return ret;
}
}
/* charge fee */
mol_seg_t fee_seg = MolReader_BatchSetMapping_get_fee(&msg.seg);
mol_seg_t amount_seg = MolReader_Fee_get_amount(&fee_seg);
mol_seg_t reg_id_seg = MolReader_Fee_get_registry_id(&fee_seg);
uint32_t reg_id = 0;
_gw_fast_memcpy((uint8_t *)(®_id), reg_id_seg.ptr, sizeof(uint32_t));
uint256_t fee_amount = {0};
_gw_fast_memcpy((uint8_t *)(&fee_amount), (uint8_t *)amount_seg.ptr,
sizeof(uint128_t));
ret = handle_fee(&ctx, reg_id, fee_amount);
if (ret != 0) {
return ret;
}
} else {
return GW_FATAL_UNKNOWN_ARGS;
}
return gw_finalize(&ctx);
}