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
// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Helper utilities around pre-compiles.
//!
//! This file contains a number of functions for Solidity type encoding
//! and decoding. Notably these implementations don't require an allocator,
//! which is why they are here in the first place (e.g. `alloy-core` requires
//! an allocator for the Solidity `bytes` type).
/// Returns the Solidity selector for `fn_sig`.
///
/// Note that this is a const function, it is evaluated at compile time.
///
/// # Usage
///
/// ```
/// # use pallet_revive_uapi::solidity_selector;
/// let sel = solidity_selector("ownCodeHash()");
/// assert_eq!(sel, [219, 107, 220, 138]);
/// ```
pub const
/// When encoding a Rust `[u8]` to Solidity `bytes`, a small amount
/// of overhead space is required (for padding and the length word).
const SOLIDITY_BYTES_ENCODING_OVERHEAD: usize = 64;
/// Encodes a `u32` to big-endian `[u8; 32]` with padded zeros.
/// Encodes a `bool` to big-endian `[u8; 32]` with padded zeros.
/// Encodes the `bytes` argument for the Solidity ABI.
/// The result is written to `out`.
///
/// Returns the number of bytes written.
///
/// # Important
///
/// This function assumes that the encoded bytes argument follows
/// two previous other argument that takes up 32 bytes.
///
/// So e.g. `function(uint32, bool, bytes)` (with `uint32` and `bool`
/// being of word size 32 bytes). This assumption is made to calculate
/// the `offset` word.
///
/// # Developer Note
///
/// The returned layout will be
///
/// ```no_compile
/// [offset (32 bytes)] [len (32 bytes)] [data (padded to 32)]
/// ```
///
/// The `out` byte array needs to be able to hold (in the worst case)
/// 95 bytes more than `input.len()`. This is because we write the
/// following to `out`:
///
/// * The offset word → always 32 bytes.
/// * The length word → always 32 bytes.
/// * The input itself → exactly `input.len()` bytes.
/// * We pad the input to a multiple of 32 → between 0 and 31 extra bytes.
/// Simple decoder for a Solidity `bytes` type.
///
/// Returns the number of bytes written to `out`.