Skip to content

Commit 641342d

Browse files
Solidity ABI compatibility metadata improvements (#2511)
* More deserializable Solidity compatibility metadata * Generate metadata for all constructors * Update changelog
1 parent f90ad06 commit 641342d

File tree

4 files changed

+68
-71
lines changed

4 files changed

+68
-71
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212

1313
### Changed
1414
- Use marker trait for finding ink! storage `struct` during code analysis - [2499](https://github.com/use-ink/ink/pull/2499)
15+
- Solidity ABI compatibility metadata improvements - [#2511](https://github.com/use-ink/ink/pull/2511)
1516

1617
### Fixed
1718
- Update metadata version to version 6 ‒ [#2507](https://github.com/use-ink/ink/pull/2507)

crates/ink/codegen/src/generator/event.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@ impl Event<'_> {
106106

107107
quote! {
108108
::ink::metadata::sol::EventParamMetadata {
109-
name: #name,
110-
ty: #sol_ty,
109+
name: #name.into(),
110+
ty: #sol_ty.into(),
111111
is_topic: #is_topic,
112-
docs: #docs,
112+
docs: #docs.into(),
113113
}
114114
}
115115
});
@@ -129,10 +129,10 @@ impl Event<'_> {
129129
#[linkme(crate = ::ink::linkme)]
130130
static EVENT_METADATA_SOL: fn() -> ::ink::metadata::sol::EventMetadata = || {
131131
::ink::metadata::sol::EventMetadata {
132-
name: #name,
132+
name: #name.into(),
133133
is_anonymous: #is_anonymous,
134134
params: vec![ #( #params ),* ],
135-
docs: #docs,
135+
docs: #docs.into(),
136136
}
137137
};
138138
};

crates/ink/codegen/src/generator/sol/metadata.rs

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use ir::{
1717
Callable as _,
1818
InputsIter,
1919
};
20-
use itertools::Itertools;
2120
use proc_macro2::TokenStream as TokenStream2;
2221
use quote::quote;
2322
use syn::Pat;
@@ -40,7 +39,7 @@ impl GenerateCode for SolidityMetadata<'_> {
4039
fn generate_code(&self) -> TokenStream2 {
4140
let ident = self.contract.module().storage().ident();
4241
let name = ident.to_string();
43-
let ctor = self.constructor();
42+
let ctors = self.constructors();
4443
let msgs = self.messages();
4544
let docs = extract_docs(self.contract.module().attrs());
4645

@@ -52,11 +51,11 @@ impl GenerateCode for SolidityMetadata<'_> {
5251
#[no_mangle]
5352
pub fn __ink_generate_solidity_metadata() -> ::ink::metadata::sol::ContractMetadata {
5453
::ink::metadata::sol::ContractMetadata {
55-
name: #name,
56-
constructor: #ctor,
54+
name: #name.into(),
55+
constructors: vec![ #( #ctors ),* ],
5756
functions: vec![ #( #msgs ),* ],
5857
events: ::ink::collect_events_sol(),
59-
docs: #docs,
58+
docs: #docs.into(),
6059
}
6160
}
6261
};
@@ -65,36 +64,34 @@ impl GenerateCode for SolidityMetadata<'_> {
6564
}
6665

6766
impl SolidityMetadata<'_> {
68-
/// Generates Solidity ABI compatible metadata for default or first ink! constructor.
69-
fn constructor(&self) -> TokenStream2 {
70-
let ctor = self
71-
.contract
67+
/// Generates Solidity ABI compatible metadata for all ink! constructors.
68+
fn constructors(&self) -> impl Iterator<Item = TokenStream2> + '_ {
69+
self.contract
7270
.module()
7371
.impls()
7472
.flat_map(|item_impl| item_impl.iter_constructors())
75-
.find_or_first(|ctor| ctor.is_default())
76-
.expect("Expected at least one constructor");
77-
78-
let ident = ctor.ident();
79-
let name = ident.to_string();
80-
let inputs = params_info(ctor.inputs());
81-
let is_payable = ctor.is_payable();
82-
let is_default = ctor.is_default();
83-
let docs = extract_docs(ctor.attrs());
73+
.map(|ctor| {
74+
let ident = ctor.ident();
75+
let name = ident.to_string();
76+
let inputs = params_info(ctor.inputs());
77+
let is_payable = ctor.is_payable();
78+
let is_default = ctor.is_default();
79+
let docs = extract_docs(ctor.attrs());
8480

85-
quote! {
86-
::ink::metadata::sol::ConstructorMetadata {
87-
name: #name,
88-
inputs: vec![ #( #inputs ),* ],
89-
is_payable: #is_payable,
90-
is_default: #is_default,
91-
docs: #docs,
92-
}
93-
}
81+
quote! {
82+
::ink::metadata::sol::ConstructorMetadata {
83+
name: #name.into(),
84+
inputs: vec![ #( #inputs ),* ],
85+
is_payable: #is_payable,
86+
is_default: #is_default,
87+
docs: #docs.into(),
88+
}
89+
}
90+
})
9491
}
9592

9693
/// Generates Solidity ABI compatible metadata for all ink! messages.
97-
fn messages(&self) -> Vec<TokenStream2> {
94+
fn messages(&self) -> impl Iterator<Item = TokenStream2> + '_ {
9895
self.contract
9996
.module()
10097
.impls()
@@ -107,7 +104,7 @@ impl SolidityMetadata<'_> {
107104
.output()
108105
.map(|ty| {
109106
let sol_ty = sol_type(ty);
110-
quote! { ::core::option::Option::Some(#sol_ty) }
107+
quote! { ::core::option::Option::Some(#sol_ty.into()) }
111108
})
112109
.unwrap_or_else(|| {
113110
quote! { ::core::option::Option::None }
@@ -119,37 +116,34 @@ impl SolidityMetadata<'_> {
119116

120117
quote! {
121118
::ink::metadata::sol::FunctionMetadata {
122-
name: #name,
119+
name: #name.into(),
123120
inputs: vec![ #( #inputs ),* ],
124121
output: #output,
125122
mutates: #mutates,
126123
is_payable: #is_payable,
127124
is_default: #is_default,
128-
docs: #docs,
125+
docs: #docs.into(),
129126
}
130127
}
131128
})
132-
.collect()
133129
}
134130
}
135131

136132
/// Returns the Solidity ABI compatible parameter type and name for the given inputs.
137-
fn params_info(inputs: InputsIter) -> Vec<TokenStream2> {
138-
inputs
139-
.map(|input| {
140-
let ty = &*input.ty;
141-
let sol_ty = sol_type(ty);
142-
let ident = match &*input.pat {
143-
Pat::Ident(ident) => &ident.ident,
144-
_ => unreachable!("Expected an input identifier"),
145-
};
146-
let name = ident.to_string();
147-
quote! {
148-
::ink::metadata::sol::ParamMetadata {
149-
name: #name,
150-
ty: #sol_ty,
151-
}
133+
fn params_info(inputs: InputsIter) -> impl Iterator<Item = TokenStream2> + '_ {
134+
inputs.map(|input| {
135+
let ty = &*input.ty;
136+
let sol_ty = sol_type(ty);
137+
let ident = match &*input.pat {
138+
Pat::Ident(ident) => &ident.ident,
139+
_ => unreachable!("Expected an input identifier"),
140+
};
141+
let name = ident.to_string();
142+
quote! {
143+
::ink::metadata::sol::ParamMetadata {
144+
name: #name.into(),
145+
ty: #sol_ty.into(),
152146
}
153-
})
154-
.collect()
147+
}
148+
})
155149
}

crates/metadata/src/sol.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
//! Types for representing Solidity ABI compatible metadata for ink! projects.
15+
//! Types for representing Solidity ABI compatibility metadata for ink! projects.
16+
17+
use std::borrow::Cow;
1618

1719
use serde::{
1820
Deserialize,
@@ -23,82 +25,82 @@ use serde::{
2325
#[derive(Debug, Serialize, Deserialize)]
2426
pub struct ContractMetadata {
2527
/// Name of ink! contract.
26-
pub name: &'static str,
27-
/// Metadata for default or first constructor of ink! contract.
28-
pub constructor: ConstructorMetadata,
28+
pub name: Cow<'static, str>,
29+
/// Metadata for all constructors of ink! contract.
30+
pub constructors: Vec<ConstructorMetadata>,
2931
/// Metadata for all messages of ink! contract.
3032
pub functions: Vec<FunctionMetadata>,
3133
/// Metadata for all events of ink! contract.
3234
pub events: Vec<EventMetadata>,
3335
/// Documentation for ink! contract.
34-
pub docs: &'static str,
36+
pub docs: Cow<'static, str>,
3537
}
3638

3739
/// ink! constructor info for Solidity ABI compatible metadata generation.
3840
#[derive(Debug, Serialize, Deserialize)]
3941
pub struct ConstructorMetadata {
4042
/// Name of ink! constructor.
41-
pub name: &'static str,
43+
pub name: Cow<'static, str>,
4244
/// Parameter info for ink! constructor.
4345
pub inputs: Vec<ParamMetadata>,
4446
/// Whether the ink! constructor is marked as payable.
4547
pub is_payable: bool,
4648
/// Whether the ink! constructor is marked as default.
4749
pub is_default: bool,
4850
/// Documentation for ink! constructor.
49-
pub docs: &'static str,
51+
pub docs: Cow<'static, str>,
5052
}
5153

5254
/// ink! message info for Solidity ABI compatible metadata generation.
5355
#[derive(Debug, Serialize, Deserialize)]
5456
pub struct FunctionMetadata {
5557
/// Name of ink! message.
56-
pub name: &'static str,
58+
pub name: Cow<'static, str>,
5759
/// Parameter info for ink! message.
5860
pub inputs: Vec<ParamMetadata>,
5961
/// Return type of ink! message.
60-
pub output: Option<&'static str>,
62+
pub output: Option<Cow<'static, str>>,
6163
/// Whether the ink! message has a mutable self receiver.
6264
pub mutates: bool,
6365
/// Whether the ink! message is marked as payable.
6466
pub is_payable: bool,
6567
/// Whether the ink! message is marked as default.
6668
pub is_default: bool,
6769
/// Documentation for ink! message.
68-
pub docs: &'static str,
70+
pub docs: Cow<'static, str>,
6971
}
7072

7173
/// ink! event info for Solidity ABI compatible metadata generation.
7274
#[derive(Debug, Serialize, Deserialize)]
7375
pub struct EventMetadata {
7476
/// Name of ink! event.
75-
pub name: &'static str,
77+
pub name: Cow<'static, str>,
7678
/// Whether the ink! event is marked as anonymous.
7779
pub is_anonymous: bool,
7880
/// Parameter info for ink! event.
7981
pub params: Vec<EventParamMetadata>,
8082
/// Documentation for ink! event.
81-
pub docs: &'static str,
83+
pub docs: Cow<'static, str>,
8284
}
8385

8486
/// ink! constructor and message parameter info.
8587
#[derive(Debug, Serialize, Deserialize)]
8688
pub struct ParamMetadata {
8789
/// Name of parameter.
88-
pub name: &'static str,
90+
pub name: Cow<'static, str>,
8991
/// Solidity ABI type of parameter.
90-
pub ty: &'static str,
92+
pub ty: Cow<'static, str>,
9193
}
9294

9395
/// ink! event parameter info.
9496
#[derive(Debug, Serialize, Deserialize)]
9597
pub struct EventParamMetadata {
9698
/// Name of parameter.
97-
pub name: &'static str,
99+
pub name: Cow<'static, str>,
98100
/// Solidity ABI type of parameter.
99-
pub ty: &'static str,
101+
pub ty: Cow<'static, str>,
100102
/// Whether the parameter is marked as a topic (i.e. is indexed).
101103
pub is_topic: bool,
102104
/// Documentation for parameter.
103-
pub docs: &'static str,
105+
pub docs: Cow<'static, str>,
104106
}

0 commit comments

Comments
 (0)