Proposals
Types
- resourceId - 32 byte string containing the target execution contract address(hashed) and the chain id type
- Last 6 bytes reserved for chain id type (2 bytes chain type + 4 bytes chain identifier)
- Last adjacent 20 bytes for target execution contract address(hashed)
- functionSig - 4 byte function signature taken to be the
0x00000000
More on resourceId
resourceId serves the purpose of representing the target chain contract
.
In cosmwasm/cosmos-sdk
chains, the contract address is normally 63 ~ 65 bytes string
.
So, here we introduce extra tweak to contract address to make it fit into resourceId(32 bytes string).
The tweak is to keccak256(contract_address) & take last 20 bytes
.
These last 20 bytes
becomes the target execution contract address(hashed)
in the resourceId.
Finally, the resourceId is created by concatenating the following parts:
6 zeroes(6 bytes)
+ target contract(20 bytes)
+ chainIdType(6 bytes)
(Ref: #55 (comment))
More on chain_id
chain_id serves the purpose of representing the blockchain network
.
In cosmwasm/cosmos-sdk
chains, the chain_id
is string
, unlike the evm
chains(number
)
For example, the chain_id
for juno
mainnet is juno-1
.
So, here we introduce extra tweak to chain_id
to make it(string) to 4 bytes number
.
The tweak is to keccak256(chain_id(string)) & take last 4 bytes
.
These last 4 bytes
becomes the chain_id in proposals.
(Ref: #39 (comment))
More on functionSig
functionSig comes from the evm
proposal, since evm
chain contracts make use of it.
However, in cosmwasm
, functionSig is not needed, since cosmwasm
leaves only one execute entry & does multiplexing the input message for different action.
So, here we just fill the 0
in the place of functionSig(0x00000000) for compatibility with other webb
proposals.
Overarching schema
(bytes32 resourceId
, bytes4 functionSig(zeroes)
, bytes4 proposalNonce
, message(the length of this is proposal specific)
)
Terminology: We will call the (resourceId, zeroes, nonce) as the proposal header. The proposal header is a total of 40 bytes.
Example proposals
1. resourceId
Proposal
Contract Flow: Bridge/SignatureBridge
-> AnchorHandler/TokenWrapperHandler
implementation (specifically goes to setResource
within AnchorHandler/TokenWrapperHandler
)
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
2. Anchor Update Proposal
Contract Flow: Bridge/SignatureBridge
-> AnchorHandler
-> Anchor
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
3. Set/Change Wrapping Fee(fee_percentage) Proposal
Contract Flow: Bridge/SignatureBridge
-> TokenWrapperHandler
-> GovernedTokenWrapper
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
4. Add Token Proposal
Contract Flow: Bridge/SignatureBridge
-> TokenWrapperHandler
-> GovernedTokenWrapper
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
5. Remove Token Proposal
Contract Flow: Bridge/SignatureBridge
-> TokenWrapperHandler
-> GovernedTokenWrapper
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
6. Set/Update Fee Recipient Proposal
Contract Flow: Bridge/SignatureBridge
-> TokenWrapperHandler
-> GovernedTokenWrapper
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
7. MaxDepositLimit Update Proposal
Contract Flow: Bridge/SignatureBridge
-> AnchorHandler
-> VAnchor
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
8. MinWithdrawalLimit Update Proposal
Contract Flow: Bridge/SignatureBridge
-> AnchorHandler
-> VAnchor
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
9. Rescue Tokens Proposal
Contract Flow: Bridge/SignatureBridge
-> TreasuryHandler
-> Treasury
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
10. Set TreasuryHandler Proposal
Contract Flow: Bridge/SignatureBridge
-> TreasuryHandler
-> Treasury
Proposal Data: (resourceId
, functionSig
, nonce
, message
)
Total Bytes: 32 + 4 + 4 + size of message
Questions/Issues
- Unlike other proposals(
evm
or substrate
), these proposals include variant-length data.
The variant-length is mainly because of different length of address in different cosmwasm/cosmos-sdk
chains.
For example, in juno
chain, the length of contract address is 63 bytes string
juno16j49kxsffgpg38l3mha4uets7clpvntf4zrnkeuegqtz0w8xq62sw4lrvj
In terra2.0
chain, the length is 64 bytes string
terra1vknprjncslpeuwhktut96amps4t82vrrrf8ggwgq5nyfqzujcwzsxmv2xp
Is it okay to use these variant-length proposal? or should go to fixed-length proposal with padding
?
-
Another variant-length data comes from the Uint128
data type, much used in cosmwasm
contracts.
Uint128
type is serialize/deserialized in String
type, and its maximum length is 39 bytes
.
How should we handle this type? keeping variant-length data? or should go to fixed-length(39 bytes) data
-
MaxExtLimitUpdate
& MaxFeeLimitUpdate
proposals seem to be needless.
What is the reason for that?
-
For every Uint128
(u128) type, the current proposals use the 16 bytes
.
So, we should add more utils to support the conversion between raw bytes
and Uint128(or u128(or String))
.
-
The feeRecipient
proposal has one tiny issue. Since the feeRecipient
could be either contract address
(63 ~ 65
bytes) or wallet address
(43 ~ 45bytes), we could think of padding the address
to fit it into longest length(63 ~ 65).
So, as well as resourceId
approach, apply left-zero-padding
so that max length is 65 bytes
?
For example,
juno16g2rahf5846rxzp3fwlswy08fz8ccuwk03k57y (43 bytes)
becomes
0000000000000000000000juno16g2rahf5846rxzp3fwlswy08fz8ccuwk03k57y (65 bytes = 12 bytes + 43 bytes)
NOTE
In every proposal, there is sig
, which is the signature of governor
on the proposal data
.
This signature is used for verifying if the caller of SignatureBridge
contact is the real governor
.